pythonlayoutpyqt6

PyQt6: keep widget width in a layout equal


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.


Solution

  • 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