【问题标题】:PyQT Connecting lambda function to SignalPyQT 将 lambda 函数连接到 Signal
【发布时间】:2015-10-22 20:07:59
【问题描述】:

我遇到了以下问题。我正在尝试将 lambda 函数连接到 Signal 以最终传递一些额外的数据。

def createTimeComboBox(self,slotCopy):
    timeComboBox = QComboBox()

    #...

    cmd = lambda func=self.test:func()
    self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),cmd)

#...

def test(self, value):
    print value

当我运行 createTimeComboBox(), 时,我收到此错误:

TypeError: 'int' object is not callable

变化

self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),cmd)

self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),self.test)

工作正常,但我也希望能够传递slotCopy 变量,因此假设我需要使用lambda 方法。

我之前使用QPushButtonclicked() 信号完成了此操作,效果很好。

def createToDoctorButton(self,extraData):
    toDoctorButton = QPushButton()

    cmd = lambda func=self.goToDoctor:func(extraData)
    self.connect(toDoctorButton,  SIGNAL('clicked()'),cmd)

    return toDoctorButton

def goToDoctor(self,extraData):
    print extraData

我希望这是有道理的 - 有人有什么想法吗?感谢您的任何建议! 干杯 戴夫

【问题讨论】:

    标签: python pyqt


    【解决方案1】:

    你的lambda接受一个参数(func):

    lambda func=self.test:func() 
    

    虽然参数有一个默认值,但是如果传递了一个参数,它会被替换掉。查看信号currentIndexChanged(int),表明该信号将传递一个整数参数。 func 将是来自 currentIndexChanged 的整数。稍后,执行func() 将有效地尝试调用一个显然不合法的整数对象(如错误所示)

    您需要在 lambda 中添加另一个参数来“捕获”传递的参数而不覆盖 func 参数:

    cmd = lambda value, func=self.test: func(value)
    

    顺便说一句,你的test 方法需要一个参数,所以你不能只做func()

    clicked() 信号没有这个问题,因为它没有传递参数来替换默认值。

    【讨论】:

    • 太棒了,谢谢你,这真是一种享受!谢谢你解释!
    • 另外,你怎么知道参数被覆盖了?
    • @user1767754 顺便说一下信号在 Qt 中的工作方式。插槽可以有相同或更少的参数,多余的参数将被忽略。但其余的将通过。是否有该参数的默认值都没有关系。如果一个信号传递了一个参数,如果可以的话,slot 会接收它。
    【解决方案2】:

    看看这是否适合你:

    timeComboBox.currentIndexChanged.connect(self.test)
    

    这是一个小的工作示例,展示了使用和不使用 lambda 的新型信号/插槽连接:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from PyQt4 import QtCore, QtGui
    
    class myWindow(QtGui.QWidget):
        def __init__(self, parent=None):
            super(myWindow, self).__init__(parent)
    
            self.comboBox = QtGui.QComboBox(self)
            self.comboBox.addItems([str(x) for x in range(3)])
            self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged)
    
            slotLambda = lambda: self.on_comboBox_currentIndexChanged_lambda("some_value")
            self.comboBox.currentIndexChanged.connect(slotLambda)
    
        @QtCore.pyqtSlot(int)
        def on_comboBox_currentIndexChanged(self, value):
            print value
    
        @QtCore.pyqtSlot(str)
        def on_comboBox_currentIndexChanged_lambda(self, string):
            print string
    
    if __name__ == "__main__":
        import sys
    
        app = QtGui.QApplication(sys.argv)
        app.setApplicationName('myWindow')
    
        main = myWindow()
        main.show()
    
        sys.exit(app.exec_())
    

    【讨论】:

    • 嘿,谢谢!我还没有设法完成这个,但希望今天晚些时候会解决它!
    猜你喜欢
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 2017-11-01
    • 2016-07-22
    • 1970-01-01
    • 2012-05-15
    相关资源
    最近更新 更多