在pyqt的for循环中连接倍数信号/插槽

Edu*_*rdo 1 python qt pyqt signals-slots

我正在使用for loopPyQt中的多个信号/插槽。代码如下:

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

我的期望:

  • phase_scan_button单击“ 连接”按钮signal到,scan_callback slot然后将字符串phase作为参数发送到slot。同样的etalonmirrorgain

我得到的是:

  • 由于某些原因,我的函数总是将字符串gain作为所有按钮的参数传递。不知道我是不是很愚蠢(可能是)或它是一个错误。

作为参考,该slot方法:

def scan_callback(self, scan):
    print(scan) # Here I always get 'gain'
    if self.scanner.isWorking:
        self.scanner.isWorking = False
        self.scan_thread.terminate()
        self.scan_thread.wait()
    else:
        self.scanner.isWorking = True
        self.scan_thread.start()
        getattr(self.ui, '{}_scan_button' .format(
            scan)).setText('Stop Scan')
        getattr(self, '_signal{}Scan' .format(scan)).emit()
Run Code Online (Sandbox Code Playgroud)

off*_*fel 5

在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))
Run Code Online (Sandbox Code Playgroud)

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

myButtons_dict = {"phase": self.ui.phase_scan_button,
                 "etalon": self.ui.etalon_scan_button,
                 "mirror": self.ui.mirror_scan_button,
                 "gain": self.ui.gain_scan_button}

for button in myButtons_dict:
    myButtons_dict[button].clicked.connect(lambda: _, b=button self.scan_callback(scan=b))
Run Code Online (Sandbox Code Playgroud)

请注意,我如何将lambda表达式与实体变量一起使用,然后将其传递给function self.scan_callback。这样,的值就button被永久存储了。

  • 请注意GPhilo的答案。他指出了您使用方法的问题,而我的方法仅帮助您管理小部件和名称! (2认同)
  • @offeltoffel在您上一次编辑中的好技巧,尽管由于指定`scan = b`是多余的,所以我只保留了`self.scan_callback(b)`。@Eduardo,如果您想知道为什么这可以解决看似很小的更改,请[查看这个令人惊奇的问题及其答案。](/sf/ask/79305901/ -mutable-default-argument)。 (2认同)
  • @GPhilo:我认为你所说的冗余更多是一种品味问题。当然`self.scan_callback(b)` 和`self.scan_callback(scan=b)` 是一样的,但我个人喜欢跟踪哪个值被传递给函数的哪个参数。当有 3 个或更多变量要传递时,它会变得很糟糕。 (2认同)