Mutual resizing of widgets

I'm implementing an application, where a side widget can expand/shrink, so an another widget must shrink/expand. (Or the side widget can be shown over that widget, it doesn't matter, I accept both implementations). It can looks like that: enter image description here

Here is a part of my code:

class AppView:
    def __init__(self):
        self._mainWindow = QDialog(None)
        self._schedule = ScheduleView(self._mainWindow)
        self._schedule.setMinimumWidth(25)
        self._schedule.setMaximumWidth(250)
        self._tutorial = TutorialView(self._mainWindow)
        self._schedule.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        self._tutorial.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        layout = QHBoxLayout()
        layout.addWidget(self._schedule)
        layout.addWidget(self._tutorial)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 1)
        self._mainWindow.setLayout(layout)

class TutorialView(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)
        self._presenter = TutorialPresenter(self)
        self.reqReprSections.connect(self.setModel)
        self.reqReprTopics.connect(self.setModel)
        self._widget = QQuickWidget(self)
        self._widget.rootContext().setContextProperty('tutorialView', self)
        self._widget.setSource(QUrl('modules/manual/manualForm/TutorialForm.qml'))

class ScheduleView(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)
        self._presenter = SchedulePresenter(self)
        self._widget = QQuickWidget(self)
        self._widget.setResizeMode(QQuickWidget.SizeViewToRootObject)
        self._widget.rootContext().setContextProperty('scheduleView', self)
        self._widget.rootContext().setContextProperty('groupsModel', self)
        self._widget.setSource(QUrl('modules/schedule/scheduleForm/ScheduleForm.qml'))

How can I do such resizes in code?

Upvotes: 1

Views: 133

Answers (1)

eyllanesc
eyllanesc

Reputation: 244282

To get that behavior you can use a QHBoxLayout by embedding a rotated button in the middle of the side widgets. You must change the left widget's size policy so that it does not expand.

To implement the rotated button you must override the paintEvent method, in addition to modifying the size policy so that it expands vertically and not horizontally.

class ShrinkExpandButton(QPushButton):
    def __init__(self, *args, **kwargs):
        QPushButton.__init__(self, *args, **kwargs)
        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)
        self.setFixedWidth(2*self.fontMetrics().height())

    def paintEvent(self, event):
        painter = QStylePainter(self)
        painter.rotate(-90)
        painter.translate(-self.height(), 0)
        option = QStyleOptionButton()
        self.initStyleOption(option)
        size = option.rect.size()
        size.transpose()
        option.rect.setSize(size)
        painter.drawControl(QStyle.CE_PushButton, option)


class ShrinkExpandWidget(QWidget):
    def __init__(self, leftWidget, rightWiget, text, parent=None):
        QWidget.__init__(self, parent)
        button = ShrinkExpandButton(text, self)

        self.setLayout(QHBoxLayout())
        self.layout().setSpacing(0)
        self.layout().addWidget(leftWidget)
        self.layout().addWidget(button)
        self.layout().addWidget(rightWiget)
        leftWidget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)
        button.clicked.connect(lambda: leftWidget.setVisible(not leftWidget.isVisible()))

Example:

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    listWidget = QListWidget()
    for i in range(20):
        listWidget.addItem("{}".format(i))

    tableWidget = QTableWidget()
    tableWidget.setColumnCount(10)
    tableWidget.setRowCount(20)
    for i in range(tableWidget.rowCount()):
        for j in range(tableWidget.columnCount()):
            tableWidget.setItem(i, j, QTableWidgetItem("({}, {})".format(i, j)))
    listWidget.setFixedWidth(240)
    w = ShrinkExpandWidget(listWidget, tableWidget, "Shrink - Expand")
    w.resize(720, 480)
    w.show()
    sys.exit(app.exec_())

Output:

enter image description here

Upvotes: 2

Related Questions