2

I have a main layout in PyQt6 with a left and right side (QHBoxLayout containing two elements). I want both sides to always be 50% of the main window width. However, when a widget on the left side grows wider, the right side is squished smaller.

How can I keep both sides equal without setting explicit (maximum) pixel widths.

Here is a minimum example:

from PyQt6 import QtWidgets
import sys


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QHBoxLayout()
        widget_left = QtWidgets.QLabel()
        widget_left.setText("Left: long text without linebreaks")
        widget_left.setLineWidth(1)
        widget_left.setFrameStyle(QtWidgets.QFrame.Shape.Box)
        layout.addWidget(widget_left)
        widget_right = QtWidgets.QLabel()
        widget_right.setText("Right")
        widget_right.setLineWidth(1)
        widget_right.setFrameStyle(QtWidgets.QFrame.Shape.Box)
        layout.addWidget(widget_right)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)
        self.setFixedSize(300,100)

app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

With the result looking like this:

Example

As you can see, left and right don't have equal width. I also tried QGridLayout with the same result. I tried different SizePolicies, but couldn't get the result I want.

5
  • 2
    For a start, you must at least use this: QLabel.setWordWrap. Commented Oct 18 at 10:21
  • What size policies did you use and how? Using an Ignored horizontal rule for the growing widget should work as expected. Please edit your post and show us your attempts. Commented Oct 18 at 11:45
  • Sorry, but in its current form, your post cannot be properly answered if not by wild guessing (which is against SO guidelines). Please take your time to edit your post, in order to rephrase it and clarify it based on the above suggestions, otherwise it will eventually be deleted as not answerable: the fact that you're using a QLabel (which can behave differently whether you wanted or enabled wrapping) may change a lot about what could be possibly answered to you, especially if you only used the QLabel as an "example placeholder" for some other widget type. Commented Oct 22 at 2:21
  • 1
    The accepted answer solves my problem. I was missing QLabel.setWordWrap(True) AND setting the stretch factor for both sides to the same value. Setting horizontal size policy to Ignored also works though! Commented Oct 23 at 20:27
  • @Tomper Ok. For future reference, ensure that you explain more clearly what you want: for starters, in the post title and body you only mention a generic "widget", only the code shows that you're using the label, but it wasn't clear that you wanted the text to wrap (not all widgets can do it) and for what we knew you may wanted to just clip the text. Also, while setting the Ignored horizontal policy may work, it may not always acceptable for all widgets (especially those with advanced behavior such as QLabel) or peculiar layouts (eg, when using nested layouts and expanding widgets). Commented Oct 24 at 0:03

1 Answer 1

2

QBoxLayout::addWidget(QWidget *widget, int stretch** = 0**, Qt::Alignment alignment = Qt::Alignment())

void QBoxLayout::addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment())

Adds widget to the end of this box layout, with a stretch factor of stretch and alignment alignment.

The stretch factor applies only in the direction of the QBoxLayout, and is relative to the other boxes and widgets in this QBoxLayout. Widgets and boxes with higher stretch factors grow more.

If the stretch factor is 0 and nothing else in the QBoxLayout has a stretch factor greater than zero, the space is distributed according to the QWidget:sizePolicy() of each widget that's involved.

wordWrap : bool

This property holds the label's word-wrapping policy

If this property is true then label text is wrapped where necessary at word-breaks; otherwise it is not wrapped at all.

---

import sys
from PyQt6 import QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        widget = QtWidgets.QWidget()
        self.setCentralWidget(widget)
        
        widget_left = QtWidgets.QLabel()
        widget_left.setWordWrap(True)                           # +++
        
        widget_left.setText("Left: long text without linebreaks")
        widget_left.setLineWidth(1)
        widget_left.setFrameStyle(QtWidgets.QFrame.Shape.Box)
        
        widget_right = QtWidgets.QLabel()
        widget_left.setWordWrap(True)                           # +++
        widget_right.setText("Right")
        widget_right.setLineWidth(1)
        widget_right.setFrameStyle(QtWidgets.QFrame.Shape.Box)

        layout = QtWidgets.QHBoxLayout(widget)        
        layout.addWidget(widget_left, stretch =1)
        layout.addWidget(widget_right, stretch =1)

#        self.setFixedSize(300,100)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.resize(400, 100)
    window.show()
    sys.exit(app.exec())

enter image description here

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.