PyQt: How to make widget scrollable

layout, pyqt, python, python-3.x, qscrollarea

Solution

Other than the obvious typo (I'm sure you meant `QScrollArea`), I can't see anything wrong with what you've posted. So the problem must lie elsewhere in your code: a missing layout maybe?

Generally speaking, problems with scroll-areas are most often caused by failing to call `setWidgetResizable(True)` and/or failing to ensure all the relevant widgets are properly managed by layouts. Also, when dynamically adding widgets to a scroll-area it's usually desirable to add a stretchable spacer to the end of a vertical/horizontal layout so that the widgets retain their positions during resizing. (This implies dynamically created widgets should be inserted after the terminating spacer, like this: `layout.insertWidget(layout.count() - 1, widget)`).

Just to make sure we're on the same page, a minimal script based on the example code in the question works as expected for me:

PyQt5/PyQt6

from PyQt5 import QtWidgets
# from PyQt6 import QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self, val):
        super().__init__()
        mygroupbox = QtWidgets.QGroupBox('this is my groupbox')
        myform = QtWidgets.QFormLayout()
        labellist = []
        combolist = []
        for i in range(val):
            labellist.append(QtWidgets.QLabel('mylabel'))
            combolist.append(QtWidgets.QComboBox())
            myform.addRow(labellist[i],combolist[i])
        mygroupbox.setLayout(myform)
        scroll = QtWidgets.QScrollArea()
        scroll.setWidget(mygroupbox)
        scroll.setWidgetResizable(True)
        scroll.setFixedHeight(200)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(scroll)

if __name__ == '__main__':

    app = QtWidgets.QApplication(['Test'])
    window = Window(12)
    window.setGeometry(500, 300, 300, 200)
    window.show()
    app.exec_()

PyQt4

from PyQt4 import QtGui

class Window(QtGui.QWidget):
    def __init__(self, val):
        QtGui.QWidget.__init__(self)
        mygroupbox = QtGui.QGroupBox('this is my groupbox')
        myform = QtGui.QFormLayout()
        labellist = []
        combolist = []
        for i in range(val):
            labellist.append(QtGui.QLabel('mylabel'))
            combolist.append(QtGui.QComboBox())
            myform.addRow(labellist[i],combolist[i])
        mygroupbox.setLayout(myform)
        scroll = QtGui.QScrollArea()
        scroll.setWidget(mygroupbox)
        scroll.setWidgetResizable(True)
        scroll.setFixedHeight(200)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(scroll)

if __name__ == '__main__':

    app = QtGui.QApplication(['Test'])
    window = Window(12)
    window.setGeometry(500, 300, 300, 200)
    window.show()
    app.exec()

Problem

I am trying to make my `QGroupBox` scrollable once it grows higher than 400px. The contents in the `QGroupBox` are generated using a for-loop. Here is an example of how it is done: ``` mygroupbox = QtGui.QGroupBox('this is my groupbox') myform = QtGui.QFormLayout() labellist = [] combolist = [] for i in range(val): labellist.append(QtGui.QLabel('mylabel')) combolist.append(QtGui.QComboBox()) myform.addRow(labellist[i],combolist[i]) mygroupbox.setLayout(myform) ``` Since the value of `val` depends on some other factors, the `myform` layout size could not be determined. In order to solve this, I added a `QScrollableArea` like this: ``` scroll = QtGui.QScrollableArea() scroll.setWidget(mygroupbox) scroll.setWidgetResizable(True) scroll.setFixedHeight(400) ``` Unfortunately, that doesn't seem to have any effect on the groupbox: there's no sign of a scrollbar. Am I missing something?

Original source