Resizing/stretching compound widget dynamically
-
I am trying to create a series of compound widgets within a QHBoxLayout with different stretch factors. This works OK. However, I'd like each widget to be able to determine its own "importance" (i.e. stretch factor) and can't understand how to do this. It looked like I should be able to call
self.sizePolicy().setHorizontalStretch()
followed byself.updateGeometry()
but this doesn't seem to cause any changes in the displayed widgets. I'd like to be able to use something like the following code, with the critical bit being in thecheckbox_changed
slot. Is this the correct approach, or should I be trying to achieve this in some other way? I'd like to end up with the situation where checking/unchecking the checkbox allows each widget to adjust its relative stretch factor - so if the box is checked, it is "important" and has a larger stretch factor than "unimportant"/unchecked widgets and therefore takes up more space.from PySide6 import QtWidgets, QtCore import logging import sys class CompoundWidget(QtWidgets.QWidget): def __init__(self, number: int): super().__init__() self.layout = QtWidgets.QGridLayout() self.checkbox = QtWidgets.QCheckBox(f"{number}") self.label = QtWidgets.QLabel(f"{number}") self.checkbox.stateChanged.connect( lambda state: self.checkbox_changed( state == QtCore.Qt.CheckState.Checked.value ) ) self.layout.addWidget(self.checkbox) self.layout.addWidget(self.label) self.setLayout(self.layout) @QtCore.Slot(bool) def checkbox_changed(self, checked: bool): logging.info("Changed") if checked: self.sizePolicy().setHorizontalStretch(5) else: self.sizePolicy().setHorizontalStretch(1) self.updateGeometry() class Stretch(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.central_layout = QtWidgets.QHBoxLayout() for x in range(4): widget = CompoundWidget(x) self.central_layout.addWidget(widget, x+1) self.central_widget = QtWidgets.QWidget() self.central_widget.setLayout(self.central_layout) self.setCentralWidget(self.central_widget) if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) app = QtWidgets.QApplication(sys.argv) app.setApplicationName("Stretch Demo") stretch = Stretch() stretch.show() sys.exit(app.exec())
-
For the benefit of future me, I needed to make the following change to read-modify-write the size policy:
@QtCore.Slot(bool) def checkbox_changed(self, checked: bool): logging.info("Changed") policy = self.sizePolicy() if checked: policy.setHorizontalStretch(5) else: policy.setHorizontalStretch(1) self.setSizePolicy(policy) logging.info("stretchfactor %d", self.sizePolicy().horizontalStretch()) self.updateGeometry()
-