Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

PySide2: Scrollable QVBoxLayout with QScrollArea ?



  • I am adding wdigets programmatically to a QVBoxLayout that is initially empty.

    I would like the vertical scroll bar to appear when the QVBoxLayout can no longer hold all the widgets in view.

    I tried with the following approach but it didn't work.

    Any specific advice ?

    import sys
    from PySide2 import QtWidgets, QtCore
    
    class Example(QtWidgets.QWidget):
        
        def __init__(self):
            super(Example, self).__init__()
            
            self.initUI()
            
        def initUI(self):
            
            scroll = QtWidgets.QScrollArea()
            scroll.setWidgetResizable(True)
            vbox = QtWidgets.QVBoxLayout()
            vbox.setAlignment(QtCore.Qt.AlignTop)
            scroll.setLayout(vbox)
            vbox.addStretch(1)
            for index in range(20):
                vbox.addWidget(QtWidgets.QPushButton('button {}'.format(index)))
            self.setLayout(vbox)    
            
            self.setGeometry(300, 300, 300, 150)
            self.setWindowTitle('Buttons')    
            self.show()
            
    def main():
        
        app = QtWidgets.QApplication(sys.argv)
        ex = Example()
        ex.show()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()
    

  • Lifetime Qt Champion

    Hi,

    Do not set the layout on the scroll area. Set it on a widget that you will set on the QScrollArea.



  • @SGaist said in PySide2: Scrollable QVBoxLayout with QScrollArea ?:

    Hi,

    Do not set the layout on the scroll area.

    Got it. I should not do this

            scroll.setLayout(vbox)
    

    Set it on a widget that you will set on the QScrollArea.

    Are you able to expand more on what you mean ? Do I create another widget for QScrollArea or is there an existing widget in QScrollArea I should be using ? Are you able to share some code example of what you mean ?

    Cheers


  • Lifetime Qt Champion

    Just create a QWidget, set the layout on it and then call QScrollArea's setWidget method as shown in the class documentation .



  • @SGaist Thank you, I got it working.

    import sys
    from PySide2 import QtWidgets, QtCore
    
    class Example(QtWidgets.QWidget):
        
        def __init__(self):
            super(Example, self).__init__()
            
            self.initUI()
            
        def initUI(self):
            
            scroll = QtWidgets.QScrollArea(self)
            vbox = QtWidgets.QVBoxLayout()
            for index in range(20):
                vbox.addWidget(QtWidgets.QPushButton('button {}'.format(index)))
            widget = QtWidgets.QWidget()
            widget.setLayout(vbox)
            scroll.setWidget(widget)
            
            self.setGeometry(300, 300, 300, 150)
            self.setWindowTitle('Buttons')    
            self.show()
            
    def main():
        
        app = QtWidgets.QApplication(sys.argv)
        ex = Example()
        ex.show()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()
    

  • Lifetime Qt Champion

    One thing: do not call show from the constructor. It's not to the widget to impose to be shown on construction.



  • @SGaist Good catch, thanks for the advice.


Log in to reply