0

I have QMainWindow that is limited by the maximum height of 900px. And I want QScrollArea to use all available space in the height axis of this window if the area has ability to grow in height.

When I run app QMainWindow chooses some value for height that is not maximum but if I stretch QMainWindow manually to maximum height QScrollArea with a lot of widgets in it looks also pretty. So why doesn't it use all availabe space from the start of the program?

Here the snippet of code that demonstrates this situation:

class UI(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setFixedWidth(500)
        self.setMaximumHeight(900)

        mainWidget = QWidget()
        mainlLayout = QVBoxLayout()
        scrollArea = QScrollArea()

        mainWidget.setLayout(mainlLayout)

        scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scrollArea.setWidgetResizable(True)
        scrollArea.setWidget(mainWidget)
        self.setCentralWidget(scrollArea)

        for i in range(30):
            buts = QHBoxLayout()
            for j in range(3):
                buts.addWidget(QPushButton('Yet Another Button'))
            mainlLayout.addLayout(buts)


def main():
    app = QApplication(sys.argv)
    ui = UI()
    ui.show()
    sys.exit(app.exec_())

Here the window after program started:
see

Here the window after stretching but looks good as well: see

  • `self.resize(self.width(), self.maximumHeight())`. – ekhumoro Mar 01 '21 at 12:23
  • @ekhumoro, yeah this works in the given case but for example, if there are only 5 rows of buttons I don't want the main window to be stretched to maximum height. I want it to be fit for the content. – Ilia Dubrovskii Mar 01 '21 at 17:17
  • See https://stackoverflow.com/questions/54351997/cannot-automatically-resize-a-qscrollarea. Basically, they increment over the height of the scroll area, resizing every time, until either the scroll bar is not visible or the height has reached the maximum. – Umbral Reaper Mar 03 '21 at 02:13
  • @UmbralReaper, thank you for the information, the result is exactly what I wanted! – Ilia Dubrovskii Mar 07 '21 at 01:06

1 Answers1

0

The code below fixes a problem with QScrollArea height:

class UI(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setFixedWidth(500)
        self.setMaximumHeight(900)

        mainWidget = QWidget()
        mainlLayout = QVBoxLayout()
        self.scrollArea = QScrollArea()

        mainWidget.setLayout(mainlLayout)

        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setWidget(mainWidget)
        self.setCentralWidget(self.scrollArea)

        for i in range(30):
            buts = QHBoxLayout()
            for j in range(3):
                buts.addWidget(QPushButton('Yet Another Button'))
            mainlLayout.addLayout(buts)

        self.show()
        QApplication.processEvents()
        self.adjustScrollArea()

    def adjustScrollArea(self):
        step = 5
        while self.scrollArea.verticalScrollBar().isVisible() and self.height() < self.maximumHeight():
            self.resize(self.width(), self.height() + step)


def main():
    app = QApplication(sys.argv)
    ui = UI()
    sys.exit(app.exec_())

I use QApplication.processEvents() because the statement self.scrollArea.verticalScrollBar().isVisible() after execution of self.show() will be valid only after gui is painted, and all events is processed.

  • I was missing `setWidgetResizable(True)`. Without this, my QScrollArea was not adjusting to the available space. – mihca Sep 01 '21 at 19:05