samox
samox

Reputation: 133

Alternative to QHBoxLayout for non-equally sized children

I'd like to be able to have a fixed size bar on the left of my window where I keep my buttons, labels, etc. and a QPlainTextEdit (as a log) on the right, which should be resized dynamically when changing the overall window size.

Ideally I would like the left side to be fixed and the right to by dynamically resized.

I just googled for hours without any luck and hope that I am just too inexperienced to find a simple solution.

Upvotes: 0

Views: 471

Answers (2)

Dennis Jensen
Dennis Jensen

Reputation: 224

As the other answer suggests you can simply use Stretch BUT... you can also use that in combination with different types of boxes as such:

VCntnr-1 = QVBoxLayout()
   VCntnr-1.addWidget(Button1)
   VCntnr-1.addWidget(Button2)
   VCntnr-1.addStretch(1)
HCntnr-1 = QHBoxLayout()
    HCntnr-1.addLayout(VCntnr-1)
    HCntnr-1.addWidget(TextBox)
    HCntnr-1.addStretch(1)

This would result in your buttons and such being statically contained in the upper left corner. Of course depending on how you want the left-side arranged perhaps it might contain 2 QVBoxLayouts with some buttons in the first one Stretch and some buttons in the second one

VCntnr-1 = QVBoxLayout()
    VCntnr-1.addWidget(Button1)
    VCntnr-1.addWidget(Button2)
VCntnr-2 = QVBoxLayout()
    VCntnr-2.addWidget(Button3)
    VCntnr-2.addWidget(Button4)
VCntnr-3 = QVBoxLayout()
    HCntnr-3.addLayout(VCntnr-1)
    HCntnr-3.addStretch(1)
    HCntnr-3.addLayout(VCntnr-2)
HCntnr-1 = QHBoxLayout()
    HCntnr-1.addLayout(VCntnr-1)
    HCntnr-1.addWidget(TextBox)
    HCntnr-1.addStretch(1)

Thus the containers along with Stretches are what are used to dynamically and statically arrange the layout you are trying to achieve so don't get stuck in a single box layout use boxes judiciously to achieve your ends. There is also a GridLayout that can be used.

Now I have placed a single Button within a QHBoxLayout along with a Stretch to place it on the left or right side of its immediate container and I have used Blank labels as Spacers (although I think pyqt5 has something called a Spacer?) to put some hard space between a Label and its associated object. So it is all about using all the bits and pieces in a creative manner to render the aesthetics you are trying to achieve.

Note the above indentations are for ease of readability and would need to be removed in code.

Upvotes: 1

Heike
Heike

Reputation: 24430

You can use QHBoxLayout.setStretch() for this, e.g.

from PyQt5.QtWidgets import QWidget,QHBoxLayout, QLabel, QApplication
from PyQt5.QtCore import Qt

class MyWidget(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        layout = QHBoxLayout(self)
        label1 = QLabel('This one is fixed', self)
        label1.setAutoFillBackground(True)
        label1.setStyleSheet('background:green')

        label2 = QLabel('This one is flexible', self)
        label2.setAlignment(Qt.AlignCenter)
        label2.setAutoFillBackground(True)
        label2.setStyleSheet('background:red')

        layout.addWidget(label1)
        layout.addWidget(label2)

        # set stretch factor of first item in layout to 0 and of second item to 1
        layout.setStretch(0,0)
        layout.setStretch(1,1)

        self.resize(500,350)


if __name__=="__main__":
    app = QApplication([])
    w = MyWidget()
    w.show()
    app.exec()

Screenshot:

screenshot

Upvotes: 2

Related Questions