PyQT连接lambda函数到信号

5

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

提示:lambda函数是一种匿名函数,可以在代码中直接使用而不必定义名称。

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

我希望这有意义 - 有人有任何想法吗?感谢任何建议!祝福 戴夫
2个回答

8

您的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中信号的工作原理。槽可以有相同或更少的参数,多余的参数将被忽略。但是剩下的参数将被传递。无论该参数是否有默认值都没有关系。如果信号传递了参数,则如果槽可以接收它,它将被接收。 - Avaris

3
看看这个是否适合你:
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_())

嘿,谢谢你!我还没有来得及看这个,但希望今天晚些时候能有时间去看一下! - David Basalla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接