在 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'。
要解决此问题,一种方法是将“i”作为关键字参数传递,并在 lambda 函数中使用默认值,确保为每个创建单独的“i”绑定instance.
self._numberButtons[i].clicked.connect(lambda checked, i=i: self._number(i))
或者,可以使用 functools.partial 创建一个将“i”绑定到与每个关联的特定值的专用函数Button.
self._numberButtons[i].clicked.connect(partial(self._number, i))
这些修改保证每个回调函数捕获'i'的正确值,启用对按钮点击的适当响应。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3