在pyq中连接for循环中的多个信号/插槽

2024-10-06 09:53:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用PyQt中的for loop连接多个信号/插槽。代码如下:

# Connect Scan Callbacks
for button in ['phase', 'etalon', 'mirror', 'gain']:
    getattr(self.ui, '{}_scan_button' .format(button)).clicked.connect(
        lambda: self.scan_callback(button))

我期望的是:

  • 将单击的按钮phase_scan_button连接到scan_callbackslot,并将字符串phase作为参数发送给slot。对于etalonmirrorgain,也是一样的。在

我得到的是:

  • 由于某些原因,我的函数总是将字符串gain作为所有按钮的参数传递。不确定我是愚蠢(可能)还是一个虫子。在

作为参考,slot方法:

^{pr2}$

Tags: 字符串selfloopforscan信号mirrorbutton
3条回答

当定义了button时,lambda不存储button。描述lambda函数的代码将被解析和编译,但在实际调用lambda之前不会执行。 无论何时单击任何按钮,都会使用变量button的当前值。在循环的末尾,button包含{},这将导致您看到的行为。在

试试这个:

funcs = []
for button in ['phase', 'etalon', 'mirror', 'gain']:
    funcs.append( lambda : print(button))

for fn in funcs:
  fn()

输出为:

^{pr2}$

扩展示例,作为lambda不存储button值的证据请注意,如果button停止存在,则会出现一个错误:

del button
for fn in funcs:
  fn()

有输出

funcs.append( lambda : print(button))
NameError: name 'button' is not defined

如前所述:Connecting slots and signals in PyQt4 in a loop 使用functools.partial是解决这个问题的一个很好的方法。在

一天来一直在和OP一样的问题上挣扎。在

我在pyqt中迭代多个小部件的首选方法是将它们存储为列表中的对象。在

myButtons = [self.ui.phase_scan_button, self.ui.etalon_scan_button,
             self.ui.mirror_scan_button, self.ui.gain_scan_button]
for button in myButtons:
    button.clicked.connect(lambda _, b=button: self.scan_callback(scan=b))

如果需要分别使用字符串“phase”、“etalon”、“mirror”和“gain”,可以将它们存储在另一个列表中,也可以创建一个类似于

^{pr2}$

请注意,我如何使用lambda表达式和实体变量,然后将这些变量传递到函数self.scan_callback。这样,button的值就被永久地存储起来了。在

相关问题 更多 >