【问题标题】:PyQt Automatically resize widget in scroll areaPyQt在滚动区域自动调整小部件的大小
【发布时间】:2018-07-07 15:57:49
【问题描述】:

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

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

【问题讨论】:

    标签: python pyqt pyqt5 qscrollarea


    【解决方案1】:

    您不应将小部件直接添加到 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 的大小,您必须稍后使用QTimer 调用adjustSize(),因为几何更改不会立即应用

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

    【讨论】:

    • 好的。这行得通。 self.scroll_widget 仍然始终保持相同的大小。有没有办法让它(红色部分)实际调整大小以适合 2 个小部件?这样在过滤某些内容时滚动条也会消失。
    • @Daniel 我已经更新了答案(请注意,我已经更改了您的代码以使其更优雅),如果我的答案对您有帮助,请不要忘记将其标记为正确,如果您不知道怎么做,查看tour,这是最好的感谢方式。 :)
    • 谢谢!这正是我想要的!
    猜你喜欢
    • 2014-02-26
    • 1970-01-01
    • 2017-11-14
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多