PyQt在连接到信号时将参数发送到插槽

Posted

技术标签:

【中文标题】PyQt在连接到信号时将参数发送到插槽【英文标题】:PyQt sending parameter to slot when connecting to a signal 【发布时间】:2010-10-30 17:53:58 【问题描述】:

我有一个任务栏菜单,当单击它时,它会连接到获取触发事件的插槽。现在的问题是我想知道单击了哪个菜单项,但我不知道如何将该信息发送到连接的功能。这里是用来连接动作和函数的:

QtCore.QObject.connect(menuAction, 'triggered()', menuClickedFunc)

我知道有些事件会返回一个值,但trigger() 没有。那么我该如何实现呢?我必须自己发出信号吗?

【问题讨论】:

【参考方案1】:

使用lambda

这是来自PyQt book 的示例:

self.connect(button3, SIGNAL("clicked()"),
    lambda who="Three": self.anyButton(who))

顺便说一句,你也可以使用functools.partial,但我发现lambda的方法更简单明了。

【讨论】:

嘿,非常感谢!完全救了我很多挫折。我可能应该得到那本书...... 很棒的答案,这正是我想要的 答案已过时,请参阅 Dominique Terrs 答案【参考方案2】:

正如已经提到的here,您可以使用 lambda 函数将额外的参数传递给您要执行的方法。

在本例中,您可以将字符串 obj 传递给按下按钮时调用的函数 AddControl()。

# Create the build button with its caption
self.build_button = QPushButton('&Build Greeting', self)
# Connect the button's clicked signal to AddControl
self.build_button.clicked.connect(lambda: self.AddControl('fooData'))
def AddControl(self, name):
    print name

来源:snip2code - Using Lambda Function To Pass Extra Argument in PyQt4

【讨论】:

这应该是被接受的答案,因为之前接受的答案方法现在已经过时了。 如果你打算用 lambda 传递变量你应该知道 lambda 会导致内存泄漏,如果信号没有正确断开 (***.com/q/61871629/5148062) 传递小变量但传递时可能可以忽略不计列表可能会杀死您的应用【参考方案3】:

使用 functools.partial

否则,如果您使用 lambda,您会发现在脚本运行时无法动态传递参数。

【讨论】:

想用一些证据来支持这一点吗? 您可以很好地将参数动态传递到创建的 lambda 中,因为 lambda(就像普通的 def'ed 函数)是闭包,因此可以从其封闭范围中捕获绑定。 (是的,这也意味着作为第三种选择,您可以使用本地 def'ed 函数动态地将参数传递给它。)此外,不要忘记您可以使用默认参数将动态值传递给 both。然而,话虽如此,我个人也更喜欢functools.partial,我自己的原因是它“感觉”比lambda 更轻量级(没有声称它确实如此)。【参考方案4】:

我还想补充一点,如果您只需要找出发送信号的小部件,您可以使用sender 方法。例如:

def menuClickedFunc(self):
    # The sender object:
    sender = self.sender()
    # The sender object's name:
    senderName = sender.objectName()
    print senderName

【讨论】:

【参考方案5】:

一般来说,您应该将每个菜单项连接到不同的插槽,并让每个插槽仅处理它自己的菜单项的功能。例如,如果您有“保存”、“关闭”、“打开”之类的菜单项,则应该为每个菜单项创建一个单独的插槽,而不是尝试在其中包含一个带有 case 语句的插槽。

如果您不想那样做,您可以使用QObject::sender() 函数来获取指向发送者的指针(即:发出信号的对象)。不过,我想听听更多关于您要完成的工作。

【讨论】:

OP 正在询问完全合法的需求。有时许多菜单项是自动生成的(或者只是非常相似)并且应该引用同一个插槽。在 PyQt 中有一个标准的方法来实现这一点,这在本书和教程中被推荐。

以上是关于PyQt在连接到信号时将参数发送到插槽的主要内容,如果未能解决你的问题,请参考以下文章

PyQt 和 QML:如何在一个插槽或函数中处理多个信号

如何将信号连接到不同线程中的插槽

将 QML 信号连接到 PySide2 插槽

如何将 PyQt 插槽从后台线程连接到 gui 线程

Pyqt将插槽连接到具有默认参数的函数而没有lambda [重复]

pyqt4在线程中向主线程中的插槽发出信号