使用 QScrollArea 折叠子部件
Using QScrollArea collapses children widgets
我正在尝试在 QVBoxLayout 中创建一个包含多个 Groupbox 对象的动态 GUI。由于它们很多,我将需要一个滚动区域以使最终用户可以使用它们。
所以我尝试将此选项卡的顶部小部件从 QWidget 更改为 QScrollArea。
变更前:
这是我想要的那种结果,但是有一个滚动条,因为 window 太高了。
QScrollArea变更后:
我的 GroupBox 现在已“折叠”并且没有滚动条。我尝试设置它们的大小,但它不够用,因为它们不是固定的。我搜索了文档并尝试使用 WidgetResizable 或者我尝试设置固定高度或 sizehint 但没有任何效果如我所愿。
创建 Groupbox 后,我的 QScrollArea 的 sizeHint 已经很低(大约 150px 高度)所以我想我缺少一个参数。
提供代码会很复杂,因为它很复杂。如有必要,我可以用更简单的方式重现问题。
如何重现:
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
import sys
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
v_layout = QVBoxLayout()
scroll_area = QScrollArea()
self.layout().addWidget(scroll_area)
scroll_area.setLayout(v_layout)
# v_layout.setSizeConstraint(QLayout.SetMinimumSize)
for i in range(50):
box = QGroupBox()
grid = QGridLayout()
box.setLayout(grid)
grid.addWidget(QLabel("totototo"), 0, 0)
grid.addWidget(QLineEdit(), 1, 0)
grid.addWidget(QPushButton(), 2, 0)
v_layout.addWidget(box)
self.show()
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
取消注释 # v_layout.setSizeConstraint(QLayout.SetMinimumSize)
允许组框的内容部署并修复问题的第一部分。但是还是没有滚动条。
您有 2 个错误:
不应将小部件添加到 QMainWindow 的布局中,但应使用 setCentralWidget 方法。
您不应该将布局添加到 QScrollArea,而是使用一个小部件作为其他小部件的容器,如果您使用布局,则必须激活 widgetResizable 属性。
综合以上,解决方案是:
def initUI(self):
scroll_area = QScrollArea(widgetResizable=True)
self.setCentralWidget(scroll_area)
container = QWidget()
scroll_area.setWidget(container)
v_layout = QVBoxLayout(container)
for i in range(50):
box = QGroupBox()
grid = QGridLayout()
box.setLayout(grid)
grid.addWidget(QLabel("totototo"), 0, 0)
grid.addWidget(QLineEdit(), 1, 0)
grid.addWidget(QPushButton(), 2, 0)
v_layout.addWidget(box)
self.show()
我正在尝试在 QVBoxLayout 中创建一个包含多个 Groupbox 对象的动态 GUI。由于它们很多,我将需要一个滚动区域以使最终用户可以使用它们。 所以我尝试将此选项卡的顶部小部件从 QWidget 更改为 QScrollArea。
变更前:
这是我想要的那种结果,但是有一个滚动条,因为 window 太高了。
QScrollArea变更后:
我的 GroupBox 现在已“折叠”并且没有滚动条。我尝试设置它们的大小,但它不够用,因为它们不是固定的。我搜索了文档并尝试使用 WidgetResizable 或者我尝试设置固定高度或 sizehint 但没有任何效果如我所愿。
创建 Groupbox 后,我的 QScrollArea 的 sizeHint 已经很低(大约 150px 高度)所以我想我缺少一个参数。
提供代码会很复杂,因为它很复杂。如有必要,我可以用更简单的方式重现问题。
如何重现:
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
import sys
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
v_layout = QVBoxLayout()
scroll_area = QScrollArea()
self.layout().addWidget(scroll_area)
scroll_area.setLayout(v_layout)
# v_layout.setSizeConstraint(QLayout.SetMinimumSize)
for i in range(50):
box = QGroupBox()
grid = QGridLayout()
box.setLayout(grid)
grid.addWidget(QLabel("totototo"), 0, 0)
grid.addWidget(QLineEdit(), 1, 0)
grid.addWidget(QPushButton(), 2, 0)
v_layout.addWidget(box)
self.show()
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
取消注释 # v_layout.setSizeConstraint(QLayout.SetMinimumSize)
允许组框的内容部署并修复问题的第一部分。但是还是没有滚动条。
您有 2 个错误:
不应将小部件添加到 QMainWindow 的布局中,但应使用 setCentralWidget 方法。
您不应该将布局添加到 QScrollArea,而是使用一个小部件作为其他小部件的容器,如果您使用布局,则必须激活 widgetResizable 属性。
综合以上,解决方案是:
def initUI(self):
scroll_area = QScrollArea(widgetResizable=True)
self.setCentralWidget(scroll_area)
container = QWidget()
scroll_area.setWidget(container)
v_layout = QVBoxLayout(container)
for i in range(50):
box = QGroupBox()
grid = QGridLayout()
box.setLayout(grid)
grid.addWidget(QLabel("totototo"), 0, 0)
grid.addWidget(QLineEdit(), 1, 0)
grid.addWidget(QPushButton(), 2, 0)
v_layout.addWidget(box)
self.show()