Как создать вертикальный прокручиваемый список, у которого высота элементов ограничена?

Здравствуйте! У меня возникла задача создать список контактов, размещённый в левой части элемента <b>QScrollArea</b>. Каждый элемент в этом прокручиваемом списке должен иметь фиксированную высоту и выстраиваться по вертикали с помощью верхнего выравнивания. Как можно реализовать эту функциональность? Вот предоставленный код: <br/> <br/> <pre><code class="python">from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

import sys

class Color(QWidget):

    def __init__(self, color):
        super(Color, self).__init__()
        self.setAutoFillBackground(True)

        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(color))
        self.setPalette(palette)

class UrlImage(QLabel):
    def __init__(self, url : str, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.image = QImage()
        import requests
        self.image.loadFromData(requests.get(url).content)
        self.setPixmap( QPixmap.fromImage(self.image))

class UserAvatar(QWidget):
    def __init__(self, contact, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setFixedSize(200, 40)

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Hello World")
        self.setCentralWidget(UrlImage("https://c0.wallpaperflare.com/preview/115/811/694/simple-background-abstract-slick.jpg"))

        self.contactsScroll = QScrollArea(self)
        self.contactsScroll.setGeometry(2, 0, 200, self.height())
        self.contactsScroll.setAttribute(Qt.WA_TranslucentBackground, True)
        self.contactsScroll.setStyleSheet("background-color: rgba(0,0,0,150);")
        self.contactsScroll.setLayout(QVBoxLayout())
        
        self.show()
  • 12 февраля 2025 г. 14:04
Ответы на вопрос 2
Чтобы создать вертикальный прокручиваемый список с элементами фиксированной высоты в PySide6, можно использовать `QScrollArea` для отображения списка и `QVBoxLayout` для выстраивания элементов. Также важно учесть, что высота самих элементов (в вашем случае это `UserAvatar`) также будет фиксированной.

Ниже представлена немного изменённая версия вашего кода с добавлением функциональности, необходимой для создания вертикального прокручиваемого списка контактов:

```python
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
import sys
import requests

class UrlImage(QLabel):
    def __init__(self, url: str, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.image = QImage()
        self.image.loadFromData(requests.get(url).content)
        self.setPixmap(QPixmap.fromImage(self.image))

class UserAvatar(QWidget):
    def __init__(self, contact, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setFixedHeight(40)  # Устанавливаем фиксированную высоту для каждого контакта
        layout = QHBoxLayout()
        layout.addWidget(QLabel(contact))  # Замените на соответствующий виджет для отображения контакта
        layout.setAlignment(Qt.AlignLeft)
        self.setLayout(layout)

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Hello World")
        
        # Устанавливаем фоновое изображение
        self.setCentralWidget(UrlImage("https://c0.wallpaperflare.com/preview/115/811/694/simple-background-abstract-slick.jpg"))

        # Создаем область прокрутки
        self.contactsScroll = QScrollArea(self)
        self.contactsScroll.setGeometry(2, 0, 200, 600)  # Замените высоту на требуемую
        self.contactsScroll.setWidgetResizable(True)  # Позволяем содержимому адаптироваться под размер области прокрутки

        # Создаем виджет для размещения содержимого списка
        self.contactsWidget = QWidget()
        self.contactsLayout = QVBoxLayout(self.contactsWidget)  # Используем QVBoxLayout для вертикального размещения

        # Добавляем элементы в прокручиваемый список
        for i in range(20):  # Задайте количество контактов
            user_avatar = UserAvatar(f"Contact {i+1}")
            self.contactsLayout.addWidget(user_avatar)

        self.contactsWidget.setLayout(self.contactsLayout)
        self.contactsScroll.setWidget(self.contactsWidget)  # Устанавливаем виджет в QScrollArea

        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())
```

### Объяснение изменений:
1. **`UserAvatar`:** Я добавил фиксированную высоту (`self.setFixedHeight(40)`) для каждого элемента списка.
2. **`QVBoxLayout`:** Используется для размещения элементов вертикально.
3. **`QScrollArea`:** Установлен флаг `setWidgetResizable(True)`, чтобы содержимое могло адаптироваться к размеру области прокрутки. Содержимым является виджет `contactsWidget`, который содержит `QVBoxLayout`.
4. **Добавление элементов:** Я добавил цикл для создания нескольких экземпляров `UserAvatar`, представляющих контакты.

Теперь вы сможете видеть вертикальный прокручиваемый список с фиксированной высотой элементов.
Решение 

from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

import sys

class Color(QWidget):

    def __init__(self, color):
        super(Color, self).__init__()
        self.setAutoFillBackground(True)

        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(color))
        self.setPalette(palette)

class UrlImage(QLabel):
    ImagesLoaded = {}

    def __init__(self, url : str, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.image = QImage()

        if not self.ImagesLoaded.get(url):
            import requests
            content = requests.get(url).content
            self.image.loadFromData(content)
            self.ImagesLoaded[url] = content
        else:
            self.image.loadFromData(self.ImagesLoaded[url])

        self.pixmap = QPixmap.fromImage(self.image)
        self.setPixmap( self.pixmap )

    def resizeEvent(self, event):
        self.setPixmap(self.pixmap.scaled(event.size().width(), event.size().height()))

class UserAvatar(QWidget):
    def __init__(self, contact, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setFixedSize(200, 40)

class MainWindow(QMainWindow):
    def resizeEvent(self, event):
        self.contactsScroll.setGeometry(0,0, 200, self.height())
        QMainWindow.resizeEvent(self, event)

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Hello World")
        self.setCentralWidget(UrlImage("https://c0.wallpaperflare.com/preview/115/811/694/simple-background-abstract-slick.jpg"))
        
        self.contactsScroll = QScrollArea(self)
        self.contactsScroll.setStyleSheet("""background-color: rgba(0,0,0,0);
                                          """)
        layout = QVBoxLayout()
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(0)
        self.contactsScroll._layout = layout

        for i in range (10):
            self.addContact("NICKNAME", "https://www.svgrepo.com/show/384674/account-avatar-profile-user-11.svg", "SERVICE_NAME", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSpJ27FVfkM_2ubo4TV6iQXfET93AFER9M6xA&s")
            self.addContact("NICKNAME", "https://www.svgrepo.com/show/384674/account-avatar-profile-user-11.svg", "SERVICE_NAME", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSpJ27FVfkM_2ubo4TV6iQXfET93AFER9M6xA&s")
            self.addContact("NICKNAME", "https://img.freepik.com/premium-vector/professional-male-avatar-profile-picture-employee-work_1322206-66590.jpg", "SERVICE_NAME", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8aMugg7LWDXqkWc-9JlApM4MLPXhi-EPDYA&s")
        
        self.show()

    def addContact(self, nickname : str, avatar_url : str, service_name : str, service_url : str) -> None:
        widget = QWidget()
        widget.setGeometry(0,0,200, 50)
        widget.setFixedHeight(50)
        widget.setFixedWidth(200)
        widget.setStyleSheet("""background-color: rgba(0,0,0,155)""")

        labelNickname = QLabel(nickname, parent=widget)
        labelNickname.move(widget.height(), 0)

        avatar = UrlImage(avatar_url, parent=widget)
        avatar.resize(widget.height(), widget.height())
        avatar.setStyleSheet("background-color: rgba(0,0,0,0)")

        serviceImage = UrlImage(service_url, parent=avatar)
        serviceImage.resize(avatar.width() / 2, avatar.height() / 2)
        serviceImage.move(avatar.width() / 2, avatar.height() / 2)
        
        self.contactsScroll._layout.addWidget(widget)
        self.contactsScroll._layout.addStretch()
        
        widget2 = QWidget()
        widget2.setLayout(self.contactsScroll._layout)
        self.contactsScroll.setWidget(widget2)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    app.exec()
Похожие вопросы