如图3个按钮,均设为checkable,放置在一个groupbox内成为一个按钮组,要求实现的功能:当点击某个按钮时将本按钮设为选中(setChecked(True)
,并取消选中按钮站中的其他所有按钮(setChecked(False)
)。
首先输入以下代码:
import sys
from PySide6.QtCore import Signal, QObject
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QGroupBox
class MainWindow(QMainWindow):
btn_signal = Signal(object)
def __init__(self):
super().__init__()
self.setWindowTitle("Main Window with Buttons")
self.btn_group = QGroupBox('buttonGroup', self)
self.btn_group.setGeometry(50, 50, 200, 300)
# 创建按钮
self.button1 = QPushButton('Button 1', self.btn_group)
self.button1.setGeometry(50, 50, 100, 50)
self.button2 = QPushButton('Button 2', self.btn_group)
self.button2.setGeometry(50, 120, 100, 50)
self.button3 = QPushButton('Button 3', self.btn_group)
self.button3.setGeometry(50, 190, 100, 50)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
# 按钮站的定义
btnStation = window.btn_group.children()
for b in btnStation:
b.setCheckable(True)
# 槽函数
def slot(btn):
self = btn
for b in btnStation:
b.setChecked(False)
self.setChecked(True)
for b in btnStation:
b.clicked.connect(lambda: slot(b)) # 连接信号到槽函数
sys.exit(app.exec())
看上去好像没问题,但是运行结果如下:无论点击哪一个按钮,只有按钮3被选中。
问题在于 slot
函数定义, 在 lambda: slot(b)
中,b
是一个循环变量,其值在整个循环执行期间会发生变化。这意味着在每次循环中,b
的值都会被最后一个按钮对象所覆盖,因此当任何按钮被点击时,实际上都会调用 slot(btnStation[-1])
,也就是列表中最后一个按钮的状态会始终被设置为选中,而其他按钮则会被取消选中。
使用回调和闭包:
import sys
from PySide6.QtCore import Signal, QObject
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QGroupBox
class MainWindow(QMainWindow):
btn_signal = Signal(object)
def __init__(self):
super().__init__()
self.setWindowTitle("Main Window with Buttons")
self.btn_group = QGroupBox('buttonGroup', self)
self.btn_group.setGeometry(50, 50, 200, 300)
# 创建按钮
self.button1 = QPushButton('Button 1', self.btn_group)
self.button1.setGeometry(50, 50, 100, 50)
self.button2 = QPushButton('Button 2', self.btn_group)
self.button2.setGeometry(50, 120, 100, 50)
self.button3 = QPushButton('Button 3', self.btn_group)
self.button3.setGeometry(50, 190, 100, 50)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
# 按钮站的定义
btnStation = window.btn_group.children()
for b in btnStation:
b.setCheckable(True)
# 回调
def call_slot(btn):
# 闭包
def slot():
self = btn
for b in btnStation:
b.setChecked(False)
self.setChecked(True)
return slot
for b in btnStation:
b.clicked.connect(call_slot(b)) # 连接信号到槽函数
sys.exit(app.exec())