gpt4 book ai didi

python - 在循环中连接 PyQt4 中的槽和信号

转载 作者:太空狗 更新时间:2023-10-29 19:38:01 26 4
gpt4 key购买 nike

我正在尝试使用 PyQt4 构建一个计算器,但连接来自按钮的“clicked()”信号无法按预期工作。我正在为 for 循环中的数字创建我的按钮,之后我会尝试连接它们。

def __init__(self):
for i in range(0,10):
self._numberButtons += [QPushButton(str(i), self)]
self.connect(self._numberButtons[i], SIGNAL('clicked()'), lambda : self._number(i))

def _number(self, x):
print(x)

当我点击按钮时,所有按钮都打印出“9”。为什么会这样,我该如何解决?

最佳答案

这就是作用域、名称查找和闭包在 Python 中的定义方式。

Python 仅通过赋值和函数参数列表在命名空间中引入新的绑定(bind)。因此,i 实际上并不是在 lambda 的命名空间中定义的,而是在 __init__() 的命名空间中定义的。在 lambda 中对 i 的名称查找最终在 __init__() 的命名空间中结束,其中 i 最终绑定(bind)到 9 。这称为“关闭”。

您可以通过将 i 作为具有默认值的关键字参数传递来解决这些公认的不太直观(但定义明确)的语义。如前所述,参数列表中的名称在本地命名空间中引入了新的绑定(bind),因此 lambda 中的 i 将独立于 中的 i .__init__():

self._numberButtons[i].clicked.connect(lambda checked, i=i: self._number(i))

更新:clicked 有一个默认的 checked 参数,它会覆盖 i 的值,所以它必须 被添加到关键字值之前的参数列表中。

一个更具可读性、不那么神奇的替代方案是 functools.partial:

self._numberButtons[i].clicked.connect(partial(self._number, i))

我在这里使用新式信号和槽语法只是为了方便,旧式语法的工作原理是一样的。

关于python - 在循环中连接 PyQt4 中的槽和信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4578861/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com