PyQt在滚动区域中自动调整窗口小部件的大小

时间:2018-07-07 06:26:41

标签: python pyqt pyqt5 qscrollarea

我正在尝试创建一个带有滚动区域和窗口小部件的窗口。这可行。我试图向此窗口添加一个简单的过滤器功能。这也有效。唯一的问题是,当隐藏了小部件时,滚动区域内的小部件不会保持其大小。有没有办法确保滚动区域中的小部件保持其大小?

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_())

1 个答案:

答案 0 :(得分: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()调用QTimer,因为不会立即应用几何更改

def filter(self, text):
    for widget in self.widgets:
        widget.setVisible(text in widget.name)
    QtCore.QTimer.singleShot(0, self.scroll_widget.adjustSize)