pythonqtpyside

Qt/PySide6: Add widget to QScrollArea during runtime, not showing up


I have a window with a button and a QScrollArea widget. When the button is pressed, a QLabel is supposed to be added to the QScrollArea widget. However, it's not showing up.

I know there are plenty of questions about similar issues. Most suggest using setWidgetResizable(True), which indeed makes the widget show up, but also changes its size: (docs)

If this property is set to true, the scroll area will automatically resize the widget in order to avoid scroll bars where they can be avoided, or to take advantage of extra space.

Here is the MWE:

from PySide6.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)

        button = QPushButton('Add')
        button.clicked.connect(self.add)

        centralWidget = QWidget()
        centralWidget.setLayout(QVBoxLayout())
        self.setCentralWidget(centralWidget)
        centralWidget.layout().addWidget(button)

        self.outputLayout = QVBoxLayout()
        outputWidget = QWidget()
        outputWidget.setLayout(self.outputLayout)
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidget(outputWidget)
        centralWidget.layout().addWidget(self.scrollArea)

    def add(self):
        label = QLabel('test')
        self.outputLayout.addWidget(label)


if __name__ == '__main__':
    app = QApplication()
    mainWindow = MainWindow()
    mainWindow.show()
    app.exec()

I tried adding label.show(), self.layout.update(), and self.scrollArea.update() to MainWindow.add, but to no avail. How can I make the label show up, without using setWidgetResizable?


Solution

  • After a lot of trial & error, I found a combination of methods which makes it work:

        def add(self):
            label = QLabel('test')
            self.outputLayout.addWidget(label)
            label.show()
            self.scrollArea.widget().adjustSize()
            self.scrollArea.widget().updateGeometry()
    

    Note that all three additional lines of code are required for the widget to show up and be sized properly: The show, the adjustSize, and the updateGeometry. Also, the order is important.