Кнопки
Contents
Кнопки¶
Все кнопки наследуют от абстрактного базового класса QAbstractButton. Встроенные классы кнопок:
Свойство Checkable
¶
Кнопки могут быть переключаемыми (checkable
) и нет. Поменять это можно методом setCheckable. Если кнопка переключаемая, то она может находиться в двух состояниях: включенном (checked
) и выключенном, при этом каждое последующее нажатие меняет статус кнопки. Статус кнопки всегда можно узнать методом isChecked.
Проще всего объяснить разницу между переключаемыми и не переключаемыми кнопками на конкретных примерах QPushButton
и QCheckBox
(флажок).

Кнопка QPushButton
по умолчания не является checkable
, после нажатия на неё, кнопка возвращается в исходное состояние. Кнопка QCheckbox
по умолчанию checkable
. Первое нажатие на кнопку приведёт к появлению галочки внутри неё. Повторное нажатие приведет к исчезновению это галочки. Ниже приводится код, воссоздающий окно из примера выше.
import sys
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
widget = QWidget()
layout = QHBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
# buttons
check_box = QCheckBox("Check box")
push_button = QPushButton("Push button")
layout.addWidget(check_box)
layout.addWidget(push_button)
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec()
Тем не менее QPushButton
тоже можно сделать checkable
.
Сигналы кнопок¶
clicked
— нажатие на кнопку;pressed
— зажатие кнопки;released
— отпуск кнопки;toggled
— изменения состояниеcheckable
кнопки.
QPushButton
¶
Кнопка QPushButton уже встречалась и подробно здесь обсуждаться не будет.
основной сигнал —
clicked
;методом setIcon можно установить иконку кнопки, методом setIconSize можно поменять её размер.
методом setCheckable можно сделать её переключаемой;
методом setFlat можно указать, показывать ли границу кнопки или нет;
Код под спойлером ниже демонстрирует поведение этих методов на примере так называемой toggle
кнопки.

Код.
import sys
import os
from PySide6.QtCore import QSize
from PySide6.QtGui import *
from PySide6.QtWidgets import *
class ToggleButton(QPushButton):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setCheckable(True)
self.setChecked(True)
self.setFlat(True)
self.clicked.connect(self.updateIcon)
self.icon_on = QIcon(os.path.join("..", "icons", "on-button.png"))
self.icon_off = QIcon(os.path.join("..", "icons", "off-button.png"))
self.updateIcon()
def updateIcon(self):
if self.isChecked():
self.setIcon(self.icon_on)
else:
self.setIcon(self.icon_off)
self.setIconSize(QSize(40, 30))
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
widget = QWidget()
main_layout = QVBoxLayout()
widget.setLayout(main_layout)
self.setCentralWidget(widget)
# top row
self.button = QPushButton("Button")
self.label = QLabel("Label")
self.label.setAlignment(Qt.AlignCenter)
self.edit = QLineEdit()
# bottom row
self.enable_button = ToggleButton("Enable")
self.show_button = ToggleButton("Show")
# layout
top_layout = QHBoxLayout()
top_layout.addWidget(self.button)
top_layout.addWidget(self.label)
top_layout.addWidget(self.edit)
main_layout.addLayout(top_layout)
bottom_layout = QHBoxLayout()
bottom_layout.addWidget(self.enable_button)
bottom_layout.addWidget(self.show_button)
main_layout.addLayout(bottom_layout)
# connections
self.enable_button.clicked.connect(self.on_button_enable_click)
self.show_button.clicked.connect(self.on_button_show_click)
def on_button_show_click(self):
for widget in [self.button, self.label, self.edit]:
widget.setVisible(self.show_button.isChecked())
def on_button_enable_click(self):
for widget in [self.button, self.label, self.edit]:
widget.setEnabled(self.enable_button.isChecked())
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec()
QCheckBox
¶
Флажки QCheckBox обычно представляют опции программы, которые могут быть включены и выключены без влияния на другие опции. Все QCheckBox
изначально являются переключаемыми (checkable
), а значит хранят состояние (поставлен флажок или нет), которое всегда можно узнать методом isChecked.
По умолчанию QCheckBox
может находиться в двух состояния: флажок поставлен (checked
) и флажок не поставлен (unchecked
). Методом setTristate можно сделать QCheckBox
с третьим возможным состоянием “флажок поставлен частично” (partially checked
). В таком случае состояние флажка запрашивать надо методом checkState, который возвращает enum
Qt.CheckState с тремя возможными значениями: Qt.Unchecked
, Qt.PartiallyChecked
и Qt.Checked
.
Как и у всех кнопок у QCheckBox
есть сигнал clicked
, но лучше использовать специальный сигнал stateChanged, который излучается каждый раз, когда меняется состояние (ставится флажок, или наоборот).

Код под спойлером ниже демонстрирует все перечисленные особенности QCheckBox
.
Код.
import sys
from PySide6.QtGui import *
from PySide6.QtWidgets import *
bistate_to_text = {
False: "Unchecked",
True: "Checked"
}
tristate_to_text = {
Qt.CheckState.Unchecked: "Unchecked",
Qt.CheckState.PartiallyChecked: "Partially Checked",
Qt.CheckState.Checked: "Checked"
}
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
widget = QWidget()
main_layout = QVBoxLayout()
widget.setLayout(main_layout)
self.setCentralWidget(widget)
# widgets
self.common_checkbox = QCheckBox("Common checkbox")
self.tristate_checkbox = QCheckBox("Tristate checkbox")
self.tristate_checkbox.setTristate()
self.label = QLabel("Unchecked and Unchecked")
# layout
main_layout.addWidget(self.common_checkbox)
main_layout.addWidget(self.tristate_checkbox)
main_layout.addWidget(self.label)
# connections
self.common_checkbox.stateChanged.connect(self.update_label)
self.tristate_checkbox.stateChanged.connect(self.update_label)
def update_label(self):
s1 = bistate_to_text[self.common_checkbox.isChecked()]
s2 = tristate_to_text[self.tristate_checkbox.checkState()]
self.label.setText(f"{s1} and {s2}")
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec()
QRadioButton
¶
QRadioButton предназначен для создания радиокнопок, т.е. переключаемых кнопок, которые могут быть во включенном и выключенном состоянии. Обычно радиокнопки используются для предоставления доступа “один из”, т.е. в группе радиокнопок только одна кнопка может быть активной в любой момент времени, нажатие на другую кнопку включает её, но выключает остальные.
При изменении состояния радиокнопка излучает сигнал toggled. Узнать её состояние можно методом isChecked
.
Один экземпляр QRadioButton
соответствует одной кнопке, т.е. одной альтернативе. По умолчанию все радиокнопки с общим родительским виджетом (parent
) являются взаимоисключающими, но удобнее использовать виджет QButtonGroup для этих целей. Этот виджет не предназначен для отрисовки каждой радиокнопки, а лишь следит за логическими связями между ними и за их состояниями. QButtonGroup
создаётся пустым, методом addButton в него можно добавлять кнопки. QButtonGroup
сигнал buttonClicked, если на одну из кнопок группы было произведено нажатие.
Чтобы отображать кнопки одной группы удобно использовать виджет-контейнер QGroupBox, который отображает группу любых виджетов (необязательно радиокнопки) в рамке с общим заголовком. Виджеты в нем располагаются так же, как и в QWidget
, т.е. внутри макетов.

Код под спойлером ниже создаёт группу взаимоисключающих радиокнопок, определяющих заголовок и иконку главного окна. Кнопки помещаются в QButtonGroup
для достижения эффекта взаимоисключаемости и упрощения обработки сигналов кнопок. Для отрисовки используется QGroupBox
.
Код.
import sys
import os
from PySide6.QtGui import *
from PySide6.QtWidgets import *
class ChooseIcon(QGroupBox):
def __init__(self):
super().__init__("Window icon and title")
# icons
self.python_icon = QIcon(os.path.join("..", "icons", "python.png"))
self.qt_icon = QIcon(os.path.join("..", "icons", "qt.png"))
self.phys_icon = QIcon(os.path.join("..", "icons", "phys.png"))
# buttons
self.python_button = QRadioButton("Python")
self.python_button.setIcon(self.python_icon)
self.qt_button = QRadioButton("Qt")
self.qt_button.setIcon(self.qt_icon)
self.phys_button = QRadioButton("Faculty of physics")
self.phys_button.setIcon(self.phys_icon)
# ButtonGroup
self.button_group = QButtonGroup()
self.button_group.addButton(self.python_button)
self.button_group.addButton(self.qt_button)
self.button_group.addButton(self.phys_button)
# layout
layout = QVBoxLayout()
layout.addWidget(self.python_button)
layout.addWidget(self.qt_button)
layout.addWidget(self.phys_button)
self.setLayout(layout)
# activating one button
self.python_button.setChecked(True)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 250, 130)
self.choose_icon = ChooseIcon()
self.setCentralWidget(self.choose_icon)
self.update_bar()
self.choose_icon.button_group.buttonClicked.connect(self.update_bar)
def update_bar(self):
active_button = self.choose_icon.button_group.checkedButton()
text = active_button.text()
icon = active_button.icon()
self.setWindowTitle(text)
self.setWindowIcon(icon)
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec()