在 PyQt4 中,在槽和信号之间建立连接是事件处理的基本方面。但是,当尝试连接循环内按钮发出的多个信号时,可能会出现意外行为。
为了说明此问题,请考虑以下代码:
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 中,变量的作用域由最近的封闭函数确定。在此示例中,lambda 函数和“_number”函数均在“__init__”函数中定义。由于每次迭代循环都会将相同的值 ('9') 分配给 'i',因此 lambda 函数始终捕获在 '__init__' 函数中分配给 'i' 的最后一个值,即 '9'。
要解决此问题,一种方法是在 lambda 函数中将“i”作为带有默认值的关键字参数传递,确保为每个实例创建单独的“i”绑定。
self._numberButtons[i].clicked.connect(lambda checked, i=i: self._number(i))
或者,可以使用 functools.partial 创建一个专门的函数,将“i”绑定到与每个按钮关联的特定值。
self._numberButtons[i].clicked.connect(partial(self._number, i))
这些修改保证每个回调函数捕获正确的值'i',启用对按钮点击的适当响应。
以上是为什么我的 PyQt4 按钮点击信号总是在循环内输出相同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!