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

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

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

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

【问题讨论】:

    标签: python qt4 pyqt


    【解决方案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 会导致内存泄漏,如果信号没有正确断开 (stackoverflow.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 中有一个标准的方法来实现这一点,这在本书和教程中被推荐。
      猜你喜欢
      • 2018-09-23
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 2014-03-27
      相关资源
      最近更新 更多