Dynamic Layouts Example¶
Dynamic Layouts implements dynamically placed widgets within running applications. The widget placement depends on whether Horizontal or Vertical is chosen.
# Copyright (C) 2013 Riverbank Computing Limited.
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
"""PySide6 port of the widgets/layouts/dynamiclayouts example from Qt v5.x"""
from PySide6.QtCore import Qt, QSize
from PySide6.QtWidgets import (QApplication, QDialog, QLayout, QGridLayout,
QMessageBox, QGroupBox, QSpinBox, QSlider,
QProgressBar, QDial, QDialogButtonBox,
QComboBox, QLabel)
class Dialog(QDialog):
def __init__(self):
super().__init__()
self._rotable_widgets = []
self.create_rotable_group_box()
self.create_options_group_box()
self.create_button_box()
main_layout = QGridLayout()
main_layout.addWidget(self._rotable_group_box, 0, 0)
main_layout.addWidget(self._options_group_box, 1, 0)
main_layout.addWidget(self._button_box, 2, 0)
main_layout.setSizeConstraint(QLayout.SetMinimumSize)
self._main_layout = main_layout
self.setLayout(self._main_layout)
self.setWindowTitle("Dynamic Layouts")
def rotate_widgets(self):
count = len(self._rotable_widgets)
if count % 2 == 1:
raise AssertionError("Number of widgets must be even")
for widget in self._rotable_widgets:
self._rotable_layout.removeWidget(widget)
self._rotable_widgets.append(self._rotable_widgets.pop(0))
for i in range(count // 2):
self._rotable_layout.addWidget(self._rotable_widgets[count - i - 1], 0, i)
self._rotable_layout.addWidget(self._rotable_widgets[i], 1, i)
def buttons_orientation_changed(self, index):
self._main_layout.setSizeConstraint(QLayout.SetNoConstraint)
self.setMinimumSize(0, 0)
orientation = Qt.Orientation(self._buttons_orientation_combo_box.itemData(index))
if orientation == self._button_box.orientation():
return
self._main_layout.removeWidget(self._button_box)
spacing = self._main_layout.spacing()
old_size_hint = self._button_box.sizeHint() + QSize(spacing, spacing)
self._button_box.setOrientation(orientation)
new_size_hint = self._button_box.sizeHint() + QSize(spacing, spacing)
if orientation == Qt.Orientation.Horizontal:
self._main_layout.addWidget(self._button_box, 2, 0)
self.resize(self.size() + QSize(-old_size_hint.width(), new_size_hint.height()))
else:
self._main_layout.addWidget(self._button_box, 0, 3, 2, 1)
self.resize(self.size() + QSize(new_size_hint.width(), -old_size_hint.height()))
self._main_layout.setSizeConstraint(QLayout.SetDefaultConstraint)
def show_help(self):
QMessageBox.information(self, "Dynamic Layouts Help",
"This example shows how to change layouts "
"dynamically.")
def create_rotable_group_box(self):
self._rotable_group_box = QGroupBox("Rotable Widgets")
self._rotable_widgets.append(QSpinBox())
self._rotable_widgets.append(QSlider())
self._rotable_widgets.append(QDial())
self._rotable_widgets.append(QProgressBar())
count = len(self._rotable_widgets)
for i in range(count):
element = self._rotable_widgets[(i + 1) % count]
self._rotable_widgets[i].valueChanged[int].connect(element.setValue)
self._rotable_layout = QGridLayout()
self._rotable_group_box.setLayout(self._rotable_layout)
self.rotate_widgets()
def create_options_group_box(self):
self._options_group_box = QGroupBox("Options")
buttons_orientation_label = QLabel("Orientation of buttons:")
buttons_orientation_combo_box = QComboBox()
buttons_orientation_combo_box.addItem("Horizontal", Qt.Orientation.Horizontal)
buttons_orientation_combo_box.addItem("Vertical", Qt.Vertical)
buttons_orientation_combo_box.currentIndexChanged[int].connect(
self.buttons_orientation_changed)
self._buttons_orientation_combo_box = buttons_orientation_combo_box
options_layout = QGridLayout()
options_layout.addWidget(buttons_orientation_label, 0, 0)
options_layout.addWidget(self._buttons_orientation_combo_box, 0, 1)
options_layout.setColumnStretch(2, 1)
self._options_group_box.setLayout(options_layout)
def create_button_box(self):
self._button_box = QDialogButtonBox()
close_button = self._button_box.addButton(QDialogButtonBox.Close)
help_button = self._button_box.addButton(QDialogButtonBox.Help)
rotate_widgets_button = self._button_box.addButton(
"Rotate &Widgets", QDialogButtonBox.ActionRole)
rotate_widgets_button.clicked.connect(self.rotate_widgets)
close_button.clicked.connect(self.close)
help_button.clicked.connect(self.show_help)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
dialog = Dialog()
dialog.exec()