5

我遇到了以下问题。我正在尝试将 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'sclicked()信号做过这个,效果很好。

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

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

4

2 回答 2

7

lambda接受一个参数 ( func):

lambda func=self.test:func() 

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

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

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

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

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

于 2013-01-05T21:27:41.247 回答
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_())
于 2013-01-05T18:05:58.710 回答