一、QButtonGroup 简介
QButtonGroup
继承自 QObject
,不是一个可视类,它主要是对按键进行分组,便于按键管理。
二、QButtonGroup 创建
QRadioButton(单选框)
默认会与同父类的所有单选框互斥,可以通过QButtonGroup
对单选框进行分类:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
#创建第1组 QRadioButton 按钮
cs1 = QRadioButton("特大杯",w)
cs1.move(80, 20)
cs2 = QRadioButton("大杯",w)
cs2.move(80, 40)
cs3 = QRadioButton("中杯",w)
cs3.move(80, 60)
cs4 = QRadioButton("小杯",w)
cs4.move(80, 80)
#创建一个按键组,并添加按键
cs_group = QButtonGroup(w)
cs_group.addButton(cs1)
cs_group.addButton(cs2)
cs_group.addButton(cs3)
cs_group.addButton(cs4)
drs1 = QRadioButton("咖啡",w)
drs1.move(20, 20)
drs2 = QRadioButton("可乐",w)
drs2.move(20, 40)
drs3 = QRadioButton("豆浆",w)
drs3.move(20, 60)
drs_group = QButtonGroup(w)
drs_group.addButton(drs1)
drs_group.addButton(drs2)
drs_group.addButton(drs3)
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行:
可以看到按键被分为2组:[咖啡,可乐,豆浆],[特大杯,大杯,中杯,小杯]。同组互斥,不同组则不互相影响。由于咖啡豆也是豆,所以现实生活中,豆浆就已经包含了咖啡。
第10~21行:程序创建了4个单选框,并设置了它们相对父控件的位置。
第24行: 创建一个按键分组
第25~28行:将4个按键添加到 cs_group 分租中
程序接着设置第2个分组,其原理同第1个分组。
三、功能(API)
1. 查看按钮和设置按钮ID
QButtonGroup 在添加按钮时,可以快捷的给按键设置一个ID(不指定会自动分配一个负值的ID),也可以通过buttons()
查看所有按键,button()
查看指定按键,以下程序示例了这个3个API函数的用法:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
#创建第1组 QRadioButton 按钮
cs1 = QRadioButton("第1个",w)
cs1.move(20, 20)
#设置第一个单选框被选中
cs1.setChecked(True)
cs2 = QRadioButton("第2个",w)
cs2.move(20, 40)
#创建一个按键组,并添加按键
cs_group = QButtonGroup(w)
cs_group.addButton(cs1, 1) #设置ID为1
cs_group.addButton(cs2, 2)
print(cs_group.buttons()) #打印所有按钮
print(cs_group.button(2)) #打印ID=2的按钮
print(cs_group.checkedButton()) #打印被按下的按钮
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行:
运行时,“第1个”按钮已经被选中,同时可以根据打印信息,在控制台观察buttons()
和button()
的运行情况。
2. 移除按钮
这里的移除按钮指的是将按钮移出QButtonGroup,而不是删除这个控件,通过removeButton()
来实现:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
#创建第1组 QRadioButton 按钮
cs1 = QRadioButton("第1个",w)
cs1.move(20, 20)
#设置第一个单选框被选中
cs1.setChecked(True)
cs2 = QRadioButton("第2个",w)
cs2.move(20, 40)
#创建一个按键组,并添加按键
cs_group = QButtonGroup(w)
cs_group.addButton(cs1, 1)
cs_group.addButton(cs2, 2)
#将cs2按键移出sc_group
cs_group.removeButton(cs2)
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行
第25行:移除cs2,即使文本为“第二个”的按钮。
可以发现,上述程序“第1个”按钮和“第2个”按钮并不互斥,我们可以同时选择2个,这是因为它们已经属于不同的分组,所以并不互斥:
3. ID相关操作
ID可以在按钮组添加按键的时候设置,也可以通过setId()
设置,可以通过id()
,来返回,最后还可以通过``已下程序示例了这2个API的使用:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
cs1 = QRadioButton("第1个",w)
cs1.move(20, 20)
cs1.setChecked(True)
cs2 = QRadioButton("第2个",w)
cs2.move(20, 40)
cs_group = QButtonGroup(w)
cs_group.addButton(cs1)
cs_group.addButton(cs2)
# 设置按钮ID
cs_group.setId(cs1,1) #cs1 id 为 1
cs_group.setId(cs2,2) #cs2 id 为 2
# 打印按键 id 以及被选择的按键ID
print(cs_group.id(cs1))
print(cs_group.id(cs2))
print(cs_group.checkedId())
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行:
4. 独占设置
默认情况下,同一个按键分组的单选框是互斥的,即同时只能选择一个,在QRadioButton中,可以对单个按键设置不与其他按键互斥,QButtonGroup通用有类似的函数,setExclusive()
,不同的是,当QButtonGroup设置互斥为False以后,该分组的所有按钮都不互斥了。以下程序示例了setExclusive()
的用法:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
#创建第1组 QRadioButton 按钮
cs1 = QRadioButton("特大杯",w)
cs1.move(80, 20)
cs2 = QRadioButton("大杯",w)
cs2.move(80, 40)
cs3 = QRadioButton("中杯",w)
cs3.move(80, 60)
cs4 = QRadioButton("小杯",w)
cs4.move(80, 80)
#创建一个按键组,并添加按键
cs_group = QButtonGroup(w)
cs_group.addButton(cs1)
cs_group.addButton(cs2)
cs_group.addButton(cs3)
cs_group.addButton(cs4)
# 设置cs_group不互斥
cs_group.setExclusive(False)
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行:
可以看到它们之间不互斥,甚至可以取消,基本是一个复选框了。
四、信号
QButtonGroup 有多个信号:
信号 | 含义 |
---|---|
buttonClicked(int id /QAbstractButton *button) | 按键被点击 |
buttonPressed(int id /QAbstractButton *button) | 按键被点击 |
buttonReleased(int id /QAbstractButton *button) | 按键被释放 |
buttonToggled(int id, bool checked/QAbstractButton *button, bool checked) | 按键状态改变 |
上表格列出了4个信号,但是每一个信号的参数都可以是整型类型的信号,也可以是按键对象,在实际使用中,可以在信号函数名后面添加[]
来指定发送的信号携带什么类型的参数,、
以buttonCloicked
为例,指定携带信号为id:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
# 创建4个 QRadioButton 按钮
cs1 = QRadioButton("特大杯",w)
cs1.move(80, 20)
cs2 = QRadioButton("大杯",w)
cs2.move(80, 40)
cs3 = QRadioButton("中杯",w)
cs3.move(80, 60)
cs4 = QRadioButton("小杯",w)
cs4.move(80, 80)
# 创建一个按键组,并添加按键
cs_group = QButtonGroup(w)
cs_group.addButton(cs1,1)
cs_group.addButton(cs2,2)
cs_group.addButton(cs3,3)
cs_group.addButton(cs4,4)
# 定义槽函数,并打印接收到的参数
def slot(id):
print("按键被按下了,id 为:",id)
# 连接槽函数,并制定带的参数会 int 类型
cs_group.buttonClicked[int].connect(slot)
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行:
第35行:通过[]
来指定参数
如果是多个参数,比如buttonToggled
,中括号则写入多个参数,用“,”区分开来,如:
cs_group.buttonToggled[int,bool].connect(slot)
或者是cs_group.buttonToggled[QAbstractButton,bool].connect(slot)
,slot
为槽函数的名字,请记得视具体程序修改参数。
如果我们使用了参数为按键对象的情况时候,也可以通过对象的方法id()
来获取参数:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("QButtonGrounp")
w.resize(300, 150)
# 创建4个 QRadioButton 按钮
cs1 = QRadioButton("特大杯",w)
cs1.move(80, 20)
cs2 = QRadioButton("大杯",w)
cs2.move(80, 40)
cs3 = QRadioButton("中杯",w)
cs3.move(80, 60)
cs4 = QRadioButton("小杯",w)
cs4.move(80, 80)
# 创建一个按键组,并添加按键
cs_group = QButtonGroup(w)
cs_group.addButton(cs1,1)
cs_group.addButton(cs2,2)
cs_group.addButton(cs3,3)
cs_group.addButton(cs4,4)
# 定义槽函数,并打印接收到的参数
def slot(object):
print("按键被按下了,id 为:", cs_group.id(object))
# 连接槽函数,并制定带的参数会 int 类型
cs_group.buttonClicked.connect(slot)
w.show()
if __name__ == '__main__':
sys.exit(app.exec_())
运行:
第35行:为指定参数,默认参数是对象
第32行:通过id()
,获取了该对象的 id 号
当程序只需要ID的时候,参数为ID是更方便的,因为不需要通过函数获取,但是如果需要更多的信息,只有id则是不够的,通常使用传入对象,然后根据具体情况获取所需要的信息。所以信号类型的选择,需要根据程序而定。