1

The following snippet fails to properly display the check-boxes I am adding to a layout in a widget that has been set on a QScrollArea.

from PyQt5 import QtCore, QtWidgets

class WidgetWithScroll(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        row =0
        layout = QtWidgets.QGridLayout()
        self.ckb_area = QtWidgets.QScrollArea()
        ckb_area = QtWidgets.QWidget()
        ckb_layout = QtWidgets.QVBoxLayout()
        ckb_area.setLayout(ckb_layout)

        # setting the scroll area widget here prevents us from adding widgets to the ckb_layout
        self.ckb_area.setWidget(ckb_area)

        layout.addWidget(self.ckb_area, 0, 0)
        for i in range(3):
            ckb = QtWidgets.QCheckBox(str(i))
            ckb_layout.addWidget(ckb)

        self.setLayout(layout)

if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    w = WidgetWithScroll()
    w.show()
    app.exec_()

By moving the setting of the widget onto the QScrollArea to after the checkboxes have been added to the widget, the checkboxes are properly rendered:

from PyQt5 import QtCore, QtWidgets

class WidgetWithScroll(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        row =0
        layout = QtWidgets.QGridLayout()
        self.ckb_area = QtWidgets.QScrollArea()
        ckb_area = QtWidgets.QWidget()
        ckb_layout = QtWidgets.QVBoxLayout()
        ckb_area.setLayout(ckb_layout)

        
        layout.addWidget(self.ckb_area, 0, 0)
        for i in range(3):
            ckb = QtWidgets.QCheckBox(str(i))
            ckb_layout.addWidget(ckb)

        # this line delayed to make it work:
        self.ckb_area.setWidget(ckb_area)

        self.setLayout(layout)

if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    w = WidgetWithScroll()
    w.show()
    app.exec_()

But I want to be able to update the widgets in the scroll area dynamically after the widget has initially been fully constructed. What am I missing?

Techniquab
  • 843
  • 7
  • 22
  • `self.ckb_area.setWidgetResizable(True)`. If you don't use *expanding widgets* (like QTextEdit), you might want to add `ckb_layout.setAlignment(QtCore.Qt.AlignTop)` to ensure that the layout is always "pushed" on top even when the scroll area is resized. For any other case, add a stretch at the end of the layout, and eventually use `layout.insertWidget(layout.count() - 1, widget)` if you need to add widgets after that. Alternatively use a "main" VBoxLayout, then add a nested layout (which will be the *actual* layout) and a stretch after that. This is necessary if you need a grid layout. – musicamante Jul 02 '22 at 03:48

0 Answers0