可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm stuck with the following problem. I'm trying to connect a lambda function to a Signal for passing some extra data eventually.
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
When I run createTimeComboBox(),
I get this error:
TypeError: 'int' object is not callable
Changing
self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),cmd)
to
self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),self.test)
works fine, but I would like to be able to pass the slotCopy
variable as well, so assumed that I need to use the lambda
approach.
I had done this previously with a QPushButton
's clicked()
signal and that worked fine.
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
I hope this makes sense - does anyone have any ideas? Thanks for any suggestions! Cheers Dave
回答1:
Your lambda
accepts a parameter (func
):
lambda func=self.test:func()
Although the parameter has a default, it will be replaced if a parameter is passed. Looking at the signal, currentIndexChanged(int)
, shows that the signal will pass an integer parameter. func
will be the integer coming from currentIndexChanged
. Later, doing func()
will be effectively trying to call an integer object which obviously is not legal (as the error indicates)
You need another parameter in your lambda
to "catch" the passed parameter without overriding the func
parameter:
cmd = lambda value, func=self.test: func(value)
By the way, your test
method expects a parameter, so you can't just do func()
.
You didn't have that problem with the clicked()
signal because it doesn't pass a parameter to replace the default value.
回答2:
See if this works for you:
timeComboBox.currentIndexChanged.connect(self.test)
Here is a small working example, demonstrating new style signals/slots connection with and without 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_())