首页 > 解决方案 > 无法使用 lambda 将参数传递给 pyqtslot

问题描述

我正在尝试使用 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):
    ...

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

标签: pythonpyqtqt-designer

解决方案


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


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

QtCore.QMetaObject.connectSlotsByName(...)

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

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

在您的情况下on_xOffsetSpinBox_editingFinished满足该要求,因为它有一个带有信号的xOffsetSpinBox对象,您可以检查您是否评论了您建立的连接,您会发现您仍然观察到同样的问题。QSpinBoxeditingFinished


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

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):
        # ...

推荐阅读