11. Containers
Qt container widgets are visual elements that group other widgets together to form structured interfaces - they organize layout, provide borders, and create logical sections of the UI.
11.1 QGroupBox
QGroupBox is a widget that has a frame and a title on top and allows you to display other widgets inside itself but is commonly used to group checkboxes or radiobuttons. QGroupBox does not lay out its child widgets automatically - you need to do it yourself using one of the Qt layout classes. You can set a QGroupBox to be checkable, which lets the user enable or disable all its child widgets simultaneously.
![]() |
Your task is to create a group of mutually exclusive options. You also need to be able to enable or disable the whole group. |
1 # A group box provides a frame, a title on top
2 # and displays various other widgets inside itself.
3
4 import sys
5
6 from PySide6.QtWidgets import (QApplication,
7 QWidget, QHBoxLayout, QVBoxLayout,
8 QGroupBox, QRadioButton, QLabel)
9
10
11 class Window(QWidget):
12
13 def __init__(self):
14
15 super().__init__()
16
17 layout = QHBoxLayout()
18
19 self.label = QLabel()
20 self.label.setFixedWidth(80)
21
22 # 1 - Create the group box
23 # and add a layout to it. You can't
24 # add widgets directly to the group box.
25
26 self.groupbox = QGroupBox()
27 self.groupbox.setTitle('Group box')
28
29 groupbox_layout = QVBoxLayout()
30 self.groupbox.setLayout(groupbox_layout)
31
32 # 2 - Add widgets to the layout.
33
34 self.radiobutton_1 = QRadioButton('Option 1')
35 self.radiobutton_2 = QRadioButton('Set checkable')
36 self.radiobutton_3 = QRadioButton('Set non-checkable')
37
38 groupbox_layout.addWidget(self.radiobutton_1)
39 groupbox_layout.addWidget(self.radiobutton_2)
40 groupbox_layout.addWidget(self.radiobutton_3)
41
42 # 4- Connect child widget signals with the slot
43
44 self.radiobutton_1.toggled.connect(self.on_toggled)
45 self.radiobutton_2.toggled.connect(self.on_toggled)
46 self.radiobutton_3.toggled.connect(self.on_toggled)
47
48 self.radiobutton_1.setChecked(True)
49
50 layout.addWidget(self.groupbox)
51 layout.addWidget(self.label)
52
53 self.setLayout(layout)
54
55 # 3 - Add slot method. If there are
56 # multiple radio buttons in a group box
57 # only one can be checked, unlike checkboxes.
58
59 def on_toggled(self):
60
61 if self.radiobutton_1.isChecked():
62 self.label.setText(self.radiobutton_1.text())
63 elif self.radiobutton_2.isChecked():
64 self.label.setText(self.radiobutton_2.text())
65 self.groupbox.setCheckable(True)
66 else:
67 self.label.setText(self.radiobutton_3.text())
68 self.groupbox.setCheckable(False)
69
70
71 if __name__ == '__main__':
72
73 app = QApplication(sys.argv)
74
75 main_window = Window()
76 main_window.show()
77
78 sys.exit(app.exec())
Create a
QGroupBoxobject and add a layout to it as you can’t add widgets directly. In the example, we use aQVBoxLayout.Create widgets and add them to the layout. In the example, we add three
QRadioButtons. We also set one of the radio buttons tochecked.Create the slot method to handle
QRadioButton.toggled()signals. The slot sets a label’s text to the text of the checked radiobutton and the last two radiobuttons also toggle the group boxtogglableproperty.Connect
QRadioButton.toggledsignals with the slot.

11.2 QScrollArea
If a QScrollArea’ child widget exceeds its size it provides scrollbars so that the whole child widget can be viewed.
![]() |
You need to create a simple text editor in a constrained space. |
1 # The QScrollArea class provides a
2 # scrolling view onto another widget
3
4 import sys
5
6 from PySide6.QtGui import QTextOption
7 from PySide6.QtWidgets import (QApplication,
8 QWidget, QVBoxLayout, QScrollArea, QPlainTextEdit)
9
10
11 class Window(QWidget):
12
13 def __init__(self):
14
15 super().__init__()
16
17 layout = QVBoxLayout()
18 self.setLayout(layout)
19
20 # 1 - Create the scroll area
21
22 scroll_area = QScrollArea()
23
24 # 2 - Create the widget that needs to be scrolled
25
26 text_edit = QPlainTextEdit()
27 text_edit.setWordWrapMode(QTextOption.WrapMode.NoWrap)
28
29 # 3 - Add the widget to the scroll area
30
31 scroll_area.setWidget(text_edit)
32
33 # Use this if you want the inner widget to
34 # get resized together with the scroll area.
35
36 scroll_area.setWidgetResizable(True)
37
38 layout.addWidget(scroll_area)
39
40
41 if __name__ == '__main__':
42
43 app = QApplication(sys.argv)
44
45 main_window = Window()
46 main_window.show()
47
48 sys.exit(app.exec())
Create a
QScrollAreaobjectCreate the child widget. In the example we use a
QPlainTextEditobject and set its wrap mode toWrapMode.NoWrapso that it expands when text is enteredAdd the
QPlainTextEditto the scroll area usingQScrollArea.addWidget(). We also set theQScrollArea.widgetResizableproperty toTrueso that the text box resizes along with the scroll area.
Now if you enter a long line of text in the text box the scroll area shows the horizontal scrollbar and if you enter several lines the scroll area shows the vertical scrollbar.

11.3 QToolBox
QToolBox provides a column of tabbed widget items. This doesn’t really tell you much - it is a Qt container widget pretty similar to the ubiquitous accordion widget that lets you pack multiple widgets within a relatively small space and expand or collapse them as needed. QToolBox pages are called items in the documentation.
![]() |
You need to add a collapsible set of options within a small space. |
1 # The QToolBox class provides a column of tabbed widget items
2
3 import sys
4
5 from PySide6.QtWidgets import (QApplication,
6 QWidget, QVBoxLayout, QToolBox, QPushButton, QLabel)
7
8
9 class Window(QWidget):
10
11 def __init__(self):
12
13 super().__init__()
14
15 layout = QVBoxLayout()
16 self.setLayout(layout)
17
18 # 1 - Create the toolbox
19
20 toolbox = QToolBox()
21
22 # 2 - Create the widgets (buttons in this case)
23
24 windows_button = QPushButton('Windows')
25 mac_button = QPushButton('Mac')
26 linux_widget = QWidget()
27
28 linux_widget.setLayout(QVBoxLayout())
29 debian_button = QPushButton('Debian')
30 arch_button = QPushButton('Arch')
31 linux_widget.layout().addWidget(debian_button)
32 linux_widget.layout().addWidget(arch_button)
33
34 # 3 - Add widgets to the toolbox
35
36 toolbox.addItem(windows_button, 'Win')
37 toolbox.addItem(mac_button, 'Mac')
38 toolbox.addItem(linux_widget, 'Lin')
39
40 windows_button.clicked.connect(self.on_clicked)
41 mac_button.clicked.connect(self.on_clicked)
42 debian_button.clicked.connect(self.on_clicked)
43 arch_button.clicked.connect(self.on_clicked)
44
45 self.label = QLabel()
46
47 layout.addWidget(toolbox)
48 layout.addWidget(self.label)
49
50 def on_clicked(self):
51 self.label.setText(self.sender().text() + ' clicked!')
52
53
54 if __name__ == '__main__':
55
56 app = QApplication(sys.argv)
57
58 main_window = Window()
59 main_window.show()
60
61 sys.exit(app.exec())
Create a
QToolBoxobjectCreate the child widgets. In the example we simply create three push buttons each representing a popular operating system. You can also add multiple child widgets to a page by adding them to a layout as demonstrated on the `Linux’ page.
Add the widgets to the toolbox using
QToolBox.addItem()
In the example we also handle the child push buttons clicked signals for demonstration purposes, setting a label’s text to the text of the clicked button.

11.4 QTabWidget
QTabWidget is a tabbed container widget - when you click on a tab its associated page is shown.
![]() |
Your space is limited and you need to create options for your editor styles and margins. |
1 # The QTabWidget class provides a stack of tabbed widgets. :S
2 # ie. tabs
3
4 import sys
5
6 from PySide6.QtWidgets import (QApplication, QWidget,
7 QVBoxLayout, QTabWidget, QRadioButton, QCheckBox)
8
9
10 class Window(QWidget):
11
12 def __init__(self):
13
14 super().__init__()
15
16 layout = QVBoxLayout()
17 self.setLayout(layout)
18
19 # 1 - Create the tab widget
20
21 self.tab_widget = QTabWidget()
22
23 # 2 - Create some widgets
24 # A tab contains only one widget
25 # but that widget can be a QWidget instance
26 # or some other container.
27
28 # Tab 0 widgets:
29
30 styles = QWidget()
31 styles_layout = QVBoxLayout()
32 styles_layout.addWidget(QCheckBox('Heading'))
33 styles_layout.addWidget(QCheckBox('Paragraph'))
34 styles_layout.addWidget(QCheckBox('List'))
35 styles.setLayout(styles_layout)
36
37 # Tab 1 widgets
38
39 margins = QWidget()
40 margins_layout = QVBoxLayout()
41 margins_layout.addWidget(QRadioButton('Normal'))
42 margins_layout.addWidget(QRadioButton('Wide'))
43 margins_layout.addWidget(QRadioButton('Narrow'))
44 margins.setLayout(margins_layout)
45
46 # 3 - Add tabs to the widget
47
48 self.tab_widget.addTab(styles, 'Styles')
49 self.tab_widget.addTab(margins, 'Margins')
50
51 layout.addWidget(self.tab_widget)
52
53
54 if __name__ == '__main__':
55
56 app = QApplication(sys.argv)
57
58 main_window = Window()
59 main_window.show()
60
61 sys.exit(app.exec())
Create a
QTabWidgetobject.Create its intended child widgets. Each page contains a single widget but that widget, in turn, can be a
QWidgetor a container class which allows you to pack multiple children into aQTabWidgetpage.Use
QTabWidget.addTab()to add the child widgets to the tab widget object. In the example we have twoQWidgets and add each to the tab widget. The firstQWidgethas three check boxes as its children and the secondQWidgets children are three radio buttons.
The tab indexes start with zero so the first tab has the index of 0 and the second has the index of 1. Each tab has a label (Styles and Margins in the example). You can change the tab position (North, South, West and East) and shape (Rounded and Triangular).

11.5 QSplitter
The QSplitter class lets the user resize its child widgets using the mouse.
![]() |
Your task is to create an application with three resizable panes and you want the user to be able to toggle their orientation. |
1 # The QSplitter class implements a splitter widget.
2 # A splitter lets the user control the size of
3 # child widgets by dragging the boundary between them.
4 # Any number of widgets may be controlled by a single splitter.
5
6 import sys
7
8 from PySide6.QtCore import Qt
9 from PySide6.QtWidgets import (QApplication, QWidget,
10 QVBoxLayout, QSplitter, QGroupBox, QRadioButton)
11
12
13 class Window(QWidget):
14
15 def __init__(self):
16
17 super().__init__()
18
19 layout = QVBoxLayout()
20 self.setLayout(layout)
21
22 # 1 - Create a splitter
23
24 self.splitter = QSplitter()
25
26 # 2 - Create widgets
27 # In this case it's three groupboxes
28
29 groupbox_1 = QGroupBox('Orientation')
30 groupbox_1.setLayout(QVBoxLayout())
31
32 # The radio buttons are just to demonstrate
33 # splitter orientation. I don't think changing
34 # splitter orientation at run time is that common.
35
36 self.button_horizontal = QRadioButton('Horizontal')
37 self.button_horizontal.setChecked(True)
38 self.button_vertical = QRadioButton('Vertical')
39
40 self.button_horizontal.toggled.connect(self.on_toggled)
41 self.button_vertical.toggled.connect(self.on_toggled)
42
43 groupbox_1.layout().addWidget(self.button_horizontal)
44 groupbox_1.layout().addWidget(self.button_vertical)
45
46 groupbox_2 = QGroupBox('group box 2')
47 groupbox_3 = QGroupBox('group box 3')
48
49 # 3 - Add widgets to the splitter
50
51 self.splitter.addWidget(groupbox_1)
52 self.splitter.addWidget(groupbox_2)
53 self.splitter.addWidget(groupbox_3)
54
55 layout.addWidget(self.splitter)
56
57 def on_toggled(self):
58
59 if self.button_horizontal.isChecked():
60 self.splitter.setOrientation(
61 Qt.Orientation.Horizontal)
62 else:
63 self.splitter.setOrientation(
64 Qt.Orientation.Vertical)
65
66
67 if __name__ == '__main__':
68
69 app = QApplication(sys.argv)
70
71 main_window = Window()
72 main_window.show()
73
74 sys.exit(app.exec())
Create the
QSplitterobject. It lays its child widgets horizontally by default but you can change that using theQSplitter.setOrientation()method.Create the child widgets. In the example we create three
QGroupBoxobjects. We also add two radio buttons to the first group box - selecting the buttons changes theQSplitterorientation dynamically.Add the child widgets to the splitter.

