weixin_42137986 2022-07-13 13:28 采纳率: 100%
浏览 55
已结题

求解PyQt5信号连接中lambda函数的参数在调用时改变的原因

问题遇到的现象和发生背景

初学python,遇到个小问题,代码如下。
字符串变量some_str在定义信号连接之后,值会改变。
我希望按下按钮时,用匿名函数打印变量some_str的初始值,而不是改变后的值。
我弄了几个按钮来尝试这个功能,其实已经解决了,用btn3的方案就行。
问题是,btn1的lambda local_var=some_str: print(local_var)并没有正确地保存local_var的初始值,在调用时变成False了。
这是为什么?

问题相关代码,请勿粘贴截图
import functools
import os
from PyQt5 import QtWidgets


class MainWidget(QtWidgets.QWidget):

    def __init__(self, parent=None):
        super(MainWidget, self).__init__(parent)
        layout = QtWidgets.QGridLayout(self)

        # 定义按钮
        self.btn0 = QtWidgets.QPushButton(text='按钮0')
        self.btn0.setObjectName('btn0')
        layout.addWidget(self.btn0, 0, 0)
        self.btn1 = QtWidgets.QPushButton(text='按钮1')
        self.btn1.setObjectName('btn1')
        layout.addWidget(self.btn1, 1, 0)
        self.btn2 = QtWidgets.QPushButton(text='按钮2')
        self.btn2.setObjectName('btn2')
        layout.addWidget(self.btn2, 2, 0)
        self.btn3 = QtWidgets.QPushButton(text='按钮3')
        self.btn3.setObjectName('btn3')
        layout.addWidget(self.btn3, 3, 0)

        # 变量初始值
        some_str = 'a'
        print('变量some_str的初始值为:', some_str)

        # 信号连接
        self.btn0.clicked.connect(lambda: print(some_str))
        self.btn1.clicked.connect(lambda local_var=some_str: print(local_var))
        self.btn2.clicked.connect(eval(f'lambda: print(\'{some_str!s}\')'))
        self.btn3.clicked.connect(
            functools.partial(lambda arg: print(arg), some_str))

        # 修改变量
        some_str = 'b'
        print('变量some_str修改后值为:', some_str)

        print('我希望按下按钮时,用匿名函数打印变量some_str的初始值')
        print('==========')


if __name__ == '__main__':
    import sys

    os.chdir(os.path.dirname(__file__))
    app = QtWidgets.QApplication(sys.argv)
    main_w = MainWidget()
    main_w.show()
    sys.exit(app.exec_())
运行结果及报错内容

几个按钮的返回值:
按钮0返回b(错误),因为调用lambda时some_str的值已经改成了b。
按钮1返回False(错误),我认为应该保存了定义时上下文的变量值,但奇怪的是,调用时这个值变成False了,为啥?
按钮2返回a(正确),代码太丑。
按钮3返回a(正确),最终采用。

我的解答思路和尝试过的方法
我想要达到的结果

我想搞清楚按钮1的local_var到底为啥会变成False。

  • 写回答

1条回答 默认 最新

  • llc的足迹 2022-07-13 13:37
    关注

    因为clicked信号有一个checked的参数(选中或没选中),匿名函数带参数的话就是拿到了这个checked,所以是False

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 7月22日
  • 已采纳回答 7月14日
  • 创建了问题 7月13日

悬赏问题

  • ¥15 聚类分析或者python进行数据分析
  • ¥15 如何用visual studio code实现html页面
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?