无法使用Lambda将参数传递给pyqtslot

时间:2019-07-22 23:27:58

标签: python pyqt qt-designer

我正在尝试使用lambda表达式将实例作为参数传递给插槽,但是我不断收到此错误:

TypeError: on_xOffsetSpinBox_editingFinished() missing 1 required positional argument: 'instance'

我已经尝试了lambda和partial来传递实例参数,但是两种方法都不起作用。

之所以要这样做,是因为我想在几个不同的类中重用相同的方法。

class AppWindow(QMainWindow):
  def __init__(self):
    ...
    self.ui.xOffsetSpinBox.editingFinished.connect(lambda: AppWindow.on_xOffsetSpinBox_editingFinished(self))
    ...

  @staticmethod
  def on_xOffsetSpinBox_editingFinished(instance):
    ...

我想将此静态方法用作其他对话类中另一个信号的插槽。

1 个答案:

答案 0 :(得分:1)

TL; DR; 失败的是Qt Designer提供的自动连接,而不是您的显式连接。


我假设ui是Qt Designer生成的类的对象,如果您检查pyuic生成的代码,则以下指令应为:

QtCore.QMetaObject.connectSlotsByName(...)

如果插槽具有以下模式,则connectSlotsByName()方法将进行自动连接:

def on_<object name>_<signal name>(<signal parameters>):
    # ...

在您的情况下,on_xOffsetSpinBox_editingFinished满足此要求,因为它有一个xOffsetSpinBox对象,该对象是一个QSpinBox信号的editingFinished,您可以检查是否对它发表评论建立连接后,您仍然会看到同样的问题。


可能的解决方案是更改静态方法的名称,以使其与指示的模式不匹配,例如:

class AppWindow(QMainWindow):
    def __init__(self):
        # ...
        self.ui.xOffsetSpinBox.editingFinished.connect(lambda: AppWindow.on_another_name(self))
        # ...

    @staticmethod
    def on_another_name(instance):
        # ...

另一种解决方案是通过传递与指示的模式不匹配的名称参数来使用@pyqtSlot()装饰器。

class AppWindow(QMainWindow):
    def __init__(self):
        # ...
        self.ui.xOffsetSpinBox.editingFinished.connect(lambda: AppWindow.on_xOffsetSpinBox_editingFinished(self))
        # ...

    @staticmethod
    @pyqtSlot(name="static_connection")
    def on_xOffsetSpinBox_editingFinished(instance):
        # ...