2

I am trying to create a dynamic GUI with multiple Groupbox objects in a QVBoxLayout. As there are a lot of them, I will be needing a scroll area to make them available to the end user. So I tried to change to top widget of this tab from a QWidget to a QScrollArea.

Before the change:

Before modification

This is the kind of result I want but with a scroll bar because the window is too high.

After the change to QScrollArea: After the modification

My GroupBoxs are now "collapsed" and there is not scrollbar. I tried setting their size but it is not adequate because they are not fixed. I searched the documentation and tried to use WidgetResizable or I tried to set a fixed height or the sizehint but nothing worked as I wanted.

After creating the the Groupbox, the sizeHint for my QScrollArea is already very low (around 150px of height) so I think I'm missing a parameter.

It would be complicated to provide code as it is intricate. If necessary I could recreate the problem in a simpler way.

How to reproduce:

from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
import sys

class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):
        
        v_layout = QVBoxLayout()
        scroll_area = QScrollArea()
        self.layout().addWidget(scroll_area)
        scroll_area.setLayout(v_layout)
        # v_layout.setSizeConstraint(QLayout.SetMinimumSize)

        for i in range(50):
            box = QGroupBox()
            grid = QGridLayout()
            box.setLayout(grid)
            grid.addWidget(QLabel("totototo"), 0, 0)
            grid.addWidget(QLineEdit(), 1, 0)
            grid.addWidget(QPushButton(), 2, 0)
            v_layout.addWidget(box)
        self.show()



app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

Uncommenting # v_layout.setSizeConstraint(QLayout.SetMinimumSize) allows the content of the group boxes to deploy and fixes the first part of the issue. But there is still not scroll bar.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Jao
  • 558
  • 2
  • 12
  • Boy does it look like a user interface from hell :-). It appears that maybe your group boxes have a bad size policy that makes them shrunk down. Try to play with their vertical size policy (e.g., Minimum instead of Preferred). – ypnos Feb 15 '21 at 14:54
  • Indeed it is not the simplest. I tried setting the size policy of my group boxes to Minimum or Fixed but it didn't help. Would it be of any use to change the policy of the widgets in the group boxes? – Jao Feb 15 '21 at 14:58
  • You may try but I would expect them to already be set correctly. – ypnos Feb 15 '21 at 14:59
  • Another thing to check is the size policy and constraints of the layout between scroll area and group boxes. – ypnos Feb 15 '21 at 15:01
  • 1
    Please provide a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), we cannot just "guess" what's wrong with your code - even it's highly possible that you're not correctly setting layouts for the groupboxes. – musicamante Feb 15 '21 at 15:03
  • I provided code and incorporated @ypnos proposition. Indeed, changing the size constraint on the layout containing the group boxes allows them to expand. Now I will try to find how to make the scroll bar appear. – Jao Feb 15 '21 at 15:42
  • @Jao You say that you are using QScrollArea but in your code you don't use that class, how do you explain that? – eyllanesc Feb 15 '21 at 15:45
  • I made a mistake in the example, it is now fixed. – Jao Feb 15 '21 at 15:47

1 Answers1

4

You have 2 errors:

  • A widget should not be added to the layout of a QMainWindow, but the setCentralWidget method should be used.

  • You should not add the layout to the QScrollArea but use a widget as a container for the other widgets, also if you use layouts then you have to activate the widgetResizable property.

Considering the above, the solution is:

def initUI(self):

    scroll_area = QScrollArea(widgetResizable=True)
    self.setCentralWidget(scroll_area)

    container = QWidget()
    scroll_area.setWidget(container)

    v_layout = QVBoxLayout(container)

    for i in range(50):
        box = QGroupBox()
        grid = QGridLayout()
        box.setLayout(grid)
        grid.addWidget(QLabel("totototo"), 0, 0)
        grid.addWidget(QLineEdit(), 1, 0)
        grid.addWidget(QPushButton(), 2, 0)
        v_layout.addWidget(box)

    self.show()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thank you for pointing out my mistakes. After adding your fixs to my code it now works as intended. – Jao Feb 15 '21 at 16:00