PyQt5 QScrollArea不滚动,而是调整项目大小

时间:2018-11-23 19:27:43

标签: python python-3.x pyqt pyqt5 qt-designer

我的问题完全使我发疯。

我正在使用PyQt5在Python上编写GUI应用程序。我的应用程序由多个QGroupBox组成,当用户在它们之间切换时,它们变得可见和不可见。

其中一个QGroupBoxes包含QScrollArea,其中放置了另一个QGroupBoxes。当用户向应用程序中添加信息时,可能会添加新的QGroupBoxes,因此当添加的元素过多时,QScrollArea应该允许查看所有这些。

所以元素的结构是:

QGroupBox
=>QScrollArea
=>=>QScrollAreaWidgetContents
=>=>=>QVBoxLayout
=>=>=>=>QGroupBox
=>=>=>=>=>QFormLayout
=>=>=>=>QGroupBox
=>=>=>=>=>QFormLayout

但是,即使我将内部QGroupBoxes放置在垂直布局中,然后放置在单个QScrollAreaWidgetContents中,QScrollArea也不显示任何滚动条,而是调整内部元素的大小,因此看起来像这样。

我的问题可以在此示例中总结:

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(415, 213)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(0, 0, 801, 601))
        self.groupBox.setObjectName("groupBox")
        self.scrollArea = QtWidgets.QScrollArea(self.groupBox)
        self.scrollArea.move(10, 30)
        self.scrollArea.setFixedWidth(380)
        self.scrollArea.setMinimumHeight(160)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.move(0, 0)
        self.scrollAreaWidgetContents.setFixedWidth(378)
        self.scrollAreaWidgetContents.setMinimumHeight(158)
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        MainWindow.setCentralWidget(self.centralwidget)

       QtCore.QMetaObject.connectSlotsByName(MainWindow)

class competencyBox(QWidget):
    def __init__(self, parent):
        super(competencyBox, self).__init__(parent)
        self.compCodeLineEdit = QLineEdit()
        self.compDescrpTextEdit = QTextEdit()
        self.box = QGroupBox(self)
        self.form_lay = QFormLayout(self)
        self.form_lay.addRow(QLabel("Код: "), self.compCodeLineEdit)
        self.form_lay.addRow(QLabel("Описание: "), self.compDescrpTextEdit)
        self.box.setLayout(self.form_lay)
        self.box.setFixedSize(510, 240)

class test_window(QMainWindow):
    def __init__(self):
        super(test_window, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.addBox(self.ui.scrollAreaWidgetContents, competencyBox, 4)

    def addBox(self, parent, element, number):
        vert_lay = QVBoxLayout(parent)
        for i in range(number):
            e = element(parent)
            vert_lay.addWidget(e)
        vert_lay.setSpacing(5)

您可能会注意到,我尝试了不同的方法,例如将固定大小设置为内部QGroupBoxes,在垂直布局中增加间距等,但是QScrollArea仍然忽略它们并缩小内部元素。我被困住了,不知道如何解决我的问题。请帮我。

1 个答案:

答案 0 :(得分:0)

您所遇到的主要问题是scrollAreaWidgetContents不应具有固定的大小,因为它是小部件的容器,并且如果您使用self.scrollAreaWidgetContents.setFixedWidth(378)进行设置,则scrollAreaWidgetContents的大小应是设置的大小。通过QVBoxLayout的窗口小部件。

另一个问题是CompetencyBox必须使用布局来设置QGroupBox。

from PyQt5 import QtCore, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(415, 213)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(0, 0, 801, 601))
        self.groupBox.setObjectName("groupBox")
        self.scrollArea = QtWidgets.QScrollArea(self.groupBox)
        self.scrollArea.move(10, 30)
        self.scrollArea.setFixedWidth(380)
        self.scrollArea.setMinimumHeight(160)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        MainWindow.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

class CompetencyBox(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(CompetencyBox, self).__init__(parent)
        self.compCodeLineEdit = QtWidgets.QLineEdit()
        self.compDescrpTextEdit = QtWidgets.QTextEdit()
        lay = QtWidgets.QVBoxLayout(self)
        box = QtWidgets.QGroupBox()
        lay.addWidget(box)
        form_lay = QtWidgets.QFormLayout()
        form_lay.addRow(QtWidgets.QLabel("Код: "), self.compCodeLineEdit)
        form_lay.addRow(QtWidgets.QLabel("Описание: "), self.compDescrpTextEdit)
        box.setLayout(form_lay)
        box.setFixedSize(510, 240)

class Test_Window(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(Test_Window, self).__init__(parent)
        self.setupUi(self)
        self.addBox(self.scrollAreaWidgetContents, CompetencyBox, 4)

    def addBox(self, parent, element, number):
        vert_lay = QtWidgets.QVBoxLayout(parent)
        for i in range(number):
            vert_lay.addWidget(element())
        vert_lay.setSpacing(5)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Test_Window()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

enter image description here