如何实现按键互斥
问题描述
当使用pyqt5写软件时,可能会出现几个状态按键,每个状态之间的逻辑是相互排斥的,这个时候,就需要编写代码将这几个按键分开,我第一次写软件的时候给每个按键都写了套逻辑,改的时候真的是欲哭无泪… … 这一次尝试写个新软件,于是就有了下文
以前的方法:
... ...
def line_slot(self):
"""
画笔工具-设置按键冲突,调整图像状态
"""
if self.line_action.isChecked():
self.move_action.setChecked(False)
self.frame_action.setChecked(False)
self.win_action.setChecked(False)
self.image.update_box()
if self.exist:
self.image.move_state = False
self.image.frame = False
self.image.line = True
self.update_all()
if not self.line_action.isChecked():
self.move_action.setChecked(True)
self.image.move_state = True
if self.exist:
self.image.line = False
self.update_all()
def move_slot(self):
"""
图像移动工具-设置按键冲突,调整图像状态
"""
if self.move_action.isChecked():
self.frame_action.setChecked(False)
self.line_action.setChecked(False)
self.win_action.setChecked(False)
self.image.update_box()
if self.exist:
self.image.move_state = True
self.image.line = False
self.image.frame = False
self.update_all()
if not self.move_action.isChecked():
if self.exist:
self.image.move_state = False
self.update_all()
... ...
实现以后的样子:
解决方法
后来了解到了QButtonGroup这个方法,只需要将按钮归为一组就可以互斥操作了,非常好用!
QButtonGroup
将所有按钮放到组内
# 创建按钮组并添加按钮,设置互斥
self.button_group = QButtonGroup()
self.button_group.addButton(self.button1)
self.button_group.addButton(self.button2)
self.button_group.addButton(self.button3)
self.button_group.addButton(self.button4)
self.button_group.setExclusive(True) # 确保互斥
别忘了要先将按钮设置为可被按下状态
self.button1.setCheckable(True)
QButtonGroup还支持多种按钮,包括单选按钮(QRadioButton), 复选框(QCheckBox),工具按钮(QToolButton)以及他们的混合按钮和自定义按钮,使用方法与上面的代码是一样的,就是换了个控件而已。
QActionGroup
但是用了以上的代码报错了,原因是我按钮是工具条上的QAction而不是QPushButton,这个时候就将QButtonGroup改为QActionGroup就好啦
self.atn_group = QActionGroup(self)
self.atn_group.setExclusive(True)
self.atn_group.addAction(self.move_atn)
self.atn_group.addAction(self.win_atn)
self.atn_group.addAction(self.paint_atn)
self.atn_group.addAction(self.rubber_atn)
实现后的效果:
它很方便的一点是,判断按键按下变得很简单,例如我通过判断按键按下来设置状态栏输出
self.atn_group.triggered.connect(self.on_action_triggered)
def on_action_triggered(self):
selected = self.atn_group.checkedAction()
self.statusbar.showMessage(f"当前模式:{selected.text()}")
它可以直接根据当前被按下的按钮定位状态
同样,用到其他的槽函数也很好用,这里就不多讲了,希望以上内容对你有用。