QButtonGroup
是 PyQt5 中用于管理多个按钮逻辑分组的类,常用于实现单选或多选功能。它允许将多个按钮(如 QRadioButton
、QCheckBox
或 QPushButton
)归为一组,统一处理选中状态、信号和 ID 分配。以下是详细介绍及常用方法:
一、核心功能
- 互斥选择:确保同一时间只有一个按钮被选中(默认启用,适用于单选场景)。
- 统一信号管理:通过组级信号处理所有按钮的点击、切换等事件。
- ID 绑定:为每个按钮分配唯一 ID,便于快速识别。
- 动态增删按钮:支持运行时添加或移除按钮。
二、常用方法
1. 创建与按钮操作
方法 | 说明 | 示例 |
---|---|---|
QButtonGroup(parent: QObject) | 构造函数 | group = QButtonGroup() |
addButton(button: QAbstractButton, id: int = -1) | 添加按钮并可选分配 ID | group.addButton(radio_btn, 1) |
removeButton(button: QAbstractButton) | 从组中移除按钮 | group.removeButton(btn) |
2. 互斥性与选中状态
方法 | 说明 | 示例 |
---|---|---|
setExclusive(enable: bool) | 设置是否互斥(默认 True) | group.setExclusive(False) (允许多选) |
exclusive() -> bool | 检查当前是否互斥 | if group.exclusive(): ... |
checkedButton() -> QAbstractButton | 返回当前选中的按钮(互斥模式下有效) | selected = group.checkedButton() |
checkedId() -> int | 返回选中按钮的 ID(未设置 ID 时返回 -1) | id = group.checkedId() |
3. ID 管理
方法 | 说明 | 示例 |
---|---|---|
setId(button: QAbstractButton, id: int) | 为按钮设置 ID | group.setId(btn, 1001) |
id(button: QAbstractButton) -> int | 获取按钮的 ID | btn_id = group.id(btn) |
button(id: int) -> QAbstractButton | 根据 ID 查找按钮 | btn = group.button(1001) |
4. 其他操作
方法 | 说明 | 示例 |
---|---|---|
buttons() -> List[QAbstractButton] | 获取组内所有按钮列表 | all_btns = group.buttons() |
三、信号
信号 | 说明 | 使用场景 |
---|---|---|
buttonClicked(button: QAbstractButton) | 按钮被点击时触发 | 通用点击事件 |
buttonClicked(int) | 传递按钮 ID 的点击信号 | 根据 ID 处理逻辑 |
buttonToggled(button: QAbstractButton, checked: bool) | 按钮切换状态时触发 | 监听复选框勾选状态 |
四、代码示例
1. 单选按钮组(互斥)
python
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QRadioButton, QButtonGroup, QLabel
class RadioDemo(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout(self)
# 创建单选按钮
self.radio1 = QRadioButton("选项1")
self.radio2 = QRadioButton("选项2")
self.radio3 = QRadioButton("选项3")
# 创建按钮组并添加按钮
self.group = QButtonGroup(self)
self.group.addButton(self.radio1, 1) # 分配 ID
self.group.addButton(self.radio2, 2)
self.group.addButton(self.radio3, 3)
# 监听点击事件(带 ID)
self.group.buttonClicked[int].connect(self.on_radio_clicked)
# 添加控件到布局
layout.addWidget(self.radio1)
layout.addWidget(self.radio2)
layout.addWidget(self.radio3)
self.label = QLabel("当前选中:无")
layout.addWidget(self.label)
def on_radio_clicked(self, btn_id):
self.label.setText(f"当前选中:选项{btn_id}")
app = QApplication([])
window = RadioDemo()
window.show()
app.exec_()
2. 多选按钮组(非互斥)
python
class CheckboxDemo(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout(self)
# 创建复选框
self.check1 = QCheckBox("苹果")
self.check2 = QCheckBox("香蕉")
self.check3 = QCheckBox("橙子")
# 创建非互斥按钮组
self.group = QButtonGroup(self)
self.group.setExclusive(False) # 关闭互斥
self.group.addButton(self.check1, 1)
self.group.addButton(self.check2, 2)
self.group.addButton(self.check3, 3)
# 监听切换事件
self.group.buttonToggled.connect(self.on_check_toggled)
layout.addWidget(self.check1)
layout.addWidget(self.check2)
layout.addWidget(self.check3)
self.label = QLabel("已选:无")
layout.addWidget(self.label)
def on_check_toggled(self, btn, checked):
selected = [btn.text() for btn in self.group.buttons() if btn.isChecked()]
self.label.setText(f"已选:{', '.join(selected)}")
五、注意事项
-
互斥性与按钮类型:
QRadioButton
默认互斥,但若未加入QButtonGroup
,同级按钮可能无法正确互斥。QCheckBox
需手动设置setExclusive(False)
以允许多选。
-
ID 管理:
- 若未显式分配 ID,
id(button)
返回自动生成的唯一负数 ID。
- 若未显式分配 ID,
-
内存管理:
QButtonGroup
不会自动删除子按钮,需手动管理或设置父对象。
-
动态按钮操作:
- 动态增删按钮时,需注意信号连接的更新。
六、与布局的区别
QButtonGroup | 布局类(如 QVBoxLayout) |
---|---|
逻辑分组,处理按钮状态和信号 | 物理布局,控制界面位置和排列 |
不影响界面显示 | 直接影响控件在窗口中的位置 |
通过 QButtonGroup
,可以轻松管理按钮的选中逻辑和事件处理,特别适用于表单、设置选项等需要分组控制的场景!