PyQt 在滚动区域自动调整小部件的大小
PyQt Automatically resize widget in scroll area
我正在尝试创建一个 window 带有带小部件的滚动区域。这行得通。我试图为此 window 添加一个简单的过滤功能。这也有效。唯一的问题是滚动区域内的小部件不保持它们的大小,当一些小部件被隐藏时。有没有办法确保滚动区域中的小部件保持其大小?
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_())
你不应该直接将小部件添加到 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)
我正在尝试创建一个 window 带有带小部件的滚动区域。这行得通。我试图为此 window 添加一个简单的过滤功能。这也有效。唯一的问题是滚动区域内的小部件不保持它们的大小,当一些小部件被隐藏时。有没有办法确保滚动区域中的小部件保持其大小?
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_())
你不应该直接将小部件添加到 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)