PyQt Автоматически изменяет размер виджета в области прокрутки

1

Я пытаюсь создать окно со областью прокрутки с виджетами. Это работает. Я попытался добавить в это окно простую функцию фильтра. Это также работает. Единственная проблема заключается в том, что виджеты внутри области прокрутки не сохраняют свой размер, когда некоторые скрыты. Есть ли способ убедиться, что виджеты в области прокрутки поддерживают их размер?

from PyQt5 import QtWidgets, QtCore, QtGui
import sys

# ----------------------------------------------------------------------------


class test(QtWidgets.QDialog):

    def __init__(self, *args, **kwargs):
        super(test, self).__init__(*args, **kwargs)

        self.main_layout = QtWidgets.QVBoxLayout(self)

        self.label_widget = QtWidgets.QWidget()
        self.label_layout = QtWidgets.QHBoxLayout()
        self.label_widget.setLayout(self.label_layout)
        self.main_layout.addWidget(self.label_widget)

        self.filter_field = QtWidgets.QLineEdit()
        self.label_layout.addWidget(self.filter_field)

        self.refresh_pbutton = QtWidgets.QPushButton("Refresh")
        self.label_layout.addWidget(self.refresh_pbutton)

        self.scroll_area = QtWidgets.QScrollArea()
        self.main_layout.addWidget(self.scroll_area)

        self.refresh_pbutton.clicked.connect(self.refresh)
        self.filter_field.textChanged.connect(self.filter)

        self.populate()

# ----------------------------------------------------------------------------

    def populate(self, *args, **kwargs):
        self.widgets = []
        self.scroll_widget = QtWidgets.QWidget()
        self.scroll_widget.setAutoFillBackground(True)
        self.scroll_widget.setStyleSheet("background-color:red;")
        self.scroll_layout = QtWidgets.QVBoxLayout()
        self.scroll_widget.setLayout(self.scroll_layout)

        for i in range(1, 11):
            widget = smallWidget(str(i))
            self.widgets.append(widget)
            self.scroll_layout.addWidget(widget)

        self.scroll_area.setWidget(self.scroll_widget)
        self.filter_field.setText("")

    def refresh(self):
        self.populate()

    def filter(self):
        filter_text = str(self.filter_field.text())
        for widget in self.widgets:
            if filter_text in widget.name:
                widget.show()
            else:
                widget.hide()

class smallWidget(QtWidgets.QWidget):
    def __init__(self, name, *args, **kwargs):
        super(smallWidget, self).__init__(*args, **kwargs)
        self.name = name

        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.name_label = QtWidgets.QLabel(self.name)
        self.main_layout.addWidget(self.name_label)


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)

    a = test()
    a.show()

    sys.exit(app.exec_())
Теги:
pyqt5
pyqt
qscrollarea

1 ответ

0
Лучший ответ

Вы не должны добавлять виджеты непосредственно в scroll_layout, но создавать другой макет, а в этом макете добавлять виджеты и использовать addStretch() чтобы он не занимал высоту первого макета, но необходимый.

def populate(self):
    self.widgets = []
    self.scroll_widget = QtWidgets.QWidget()
    self.scroll_widget.setAutoFillBackground(True)
    self.scroll_widget.setStyleSheet("background-color:red;")
    self.scroll_layout = QtWidgets.QVBoxLayout()
    self.scroll_widget.setLayout(self.scroll_layout)

    lay = QtWidgets.QVBoxLayout() # <---
    self.scroll_layout.addLayout(lay) # <---
    self.scroll_layout.addStretch() # <---

    for i in range(1, 11):
        widget = smallWidget(str(i))
        self.widgets.append(widget)
        lay.addWidget(widget) # <---

    self.scroll_area.setWidget(self.scroll_widget)

Обновить:

Если вы хотите, чтобы размер scroll_widget был скорректирован, вы должны adjustSize() вызвать adjustSize() с помощью QTimer поскольку изменения геометрии не применяются мгновенно

def filter(self, text):
    for widget in self.widgets:
        widget.setVisible(text in widget.name)
    QtCore.QTimer.singleShot(0, self.scroll_widget.adjustSize)
  • 0
    Хорошо. Это работает. self.scroll_widget по-прежнему всегда остается одного размера. Есть ли способ сделать это (красная часть) на самом деле изменить размер в соответствии с 2 виджетов? Таким образом, полоса прокрутки также исчезнет, когда что-то фильтруется.
  • 0
    @Daniel я уже обновил ответ (обратите внимание , что я изменил свой код , чтобы сделать его более элегантным), если мой ответ поможет вам не забудьте пометить его как правильный, если вы не знаете , как это сделать, обзор тура Это лучший способ поблагодарить. :)
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню