Qt: HBoxLayout - stop MainWindow from resizing to contents
Asked Answered
L

1

3

It seems most people are asking how to make their QMainWindow resize to its contents - I have the opposite problem, my MainWindow does resize and I don't know why.

When I set my QLabel to a longer text, my mainwindow suddenly gets bigger, and I can't find out why that happens.

The following example code basically contains:

  • A QMainWindow
    • A QWidget as central widget
      • A QVBoxLayout as a child of that
        • A LabelBar inside that.

The LabelBar is a QWidget which in turn contains:

  • A QHBoxLayout
    • Two QLabels in that.

After a second, a QTimer sets the label to a longer text to demonstrate the issue.

PyQt example code:

from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QLabel, QWidget,
                             QMainWindow, QVBoxLayout, QSizePolicy)
from PyQt5.QtCore import QTimer

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        cwidget = QWidget(self)
        self.setCentralWidget(cwidget)
        self.resize(100, 100)

        vbox = QVBoxLayout(cwidget)
        vbox.addWidget(QWidget())
        self.bar = LabelBar(self)
        vbox.addWidget(self.bar)

        timer = QTimer(self)
        timer.timeout.connect(lambda: self.bar.lbl2.setText("a" * 100))
        timer.start(1000)

class LabelBar(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        hbox = QHBoxLayout(self)
        self.lbl1 = QLabel(text="eggs")
        hbox.addWidget(self.lbl1)
        self.lbl2 = QLabel(text="spam")
        hbox.addWidget(self.lbl2)

if __name__ == '__main__':
    app = QApplication([])
    main = MainWindow()
    main.show()
    app.exec_()
Lithophyte answered 12/2, 2014 at 20:41 Comment(0)
B
4

Main window grows because it's the goal of using layouts. Layouts make size requirements for their widgets to ensure that all content is displayed correctly. Requirements depend on child widgets. For example, QLabel by default grows horizontally and require space to fit its content. There are many ways to prevent window growing, and the resulting behavior varies:

  • You can put QLabel in a QScrollArea. When label's text is too long, scrollbars will appear.
  • You can enable word wrap using self.lbl2.setWordWrap(True). As long as you set text with some spaces, QLabel will display it in several lines, and window will grow vertically a bit instead of growing horizontally.
  • You can ignore QLabel's size hint using self.lbl2.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed). QLabel's content will not affect its layout or parent widget size. Too large text will be truncated.
Beecham answered 12/2, 2014 at 20:57 Comment(1)
Number 3 was a good hint - I still wanted the label to resize when there is space (when the other label gets smaller for example). I ended up setting the sizePolicy of my LabelBar to ignored, which did what I want.Lithophyte

© 2022 - 2024 — McMap. All rights reserved.