PySide(PyQt)利用回调和闭包定义信号与槽

如图3个按钮,均设为checkable,放置在一个groupbox内成为一个按钮组,要求实现的功能:当点击某个按钮时将本按钮设为选中(setChecked(True),并取消选中按钮站中的其他所有按钮(setChecked(False))。

首先输入以下代码:

python 复制代码
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]),也就是列表中最后一个按钮的状态会始终被设置为选中,而其他按钮则会被取消选中。

使用回调和闭包:

python 复制代码
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())
相关推荐
二十雨辰19 分钟前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码30 分钟前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
前端摸鱼匠1 小时前
YOLOv8 环境配置全攻略:Python、PyTorch 与 CUDA 的和谐共生
人工智能·pytorch·python·yolo·目标检测
WangYaolove13141 小时前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码
AALoveTouch2 小时前
大麦网协议分析
javascript·python
ZH15455891312 小时前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
xcLeigh2 小时前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh2 小时前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics
YongCheng_Liang3 小时前
从零开始学 Python:自动化 / 运维开发实战(核心库 + 3 大实战场景)
python·自动化·运维开发
鸽芷咕3 小时前
为什么越来越多开发者转向 CANN 仓库中的 Python 自动化方案?
python·microsoft·自动化·cann