PyQT将lambda函数连接到Signal

时间:2013-01-05 15:45:03

标签: python pyqt

我遇到了以下问题。我正在尝试将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方法。

我之前使用QPushButton的{​​{1}}信号完成了此操作,并且运行正常。

clicked()

我希望这是有道理的 - 有没有人有任何想法?谢谢你的任何建议! 干杯 戴夫

2 个答案:

答案 0 :(得分:5)

您的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()信号没有这个问题,因为它没有传递参数来替换默认值。

答案 1 :(得分:3)

看看这是否适合你:

timeComboBox.currentIndexChanged.connect(self.test)

这是一个小工作示例,演示了有和没有lambdas的新风格信号/插槽连接:

#!/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_())