2013-01-05 186 views
5

我遇到以下問題。我試圖將一個lambda函數連接到一個Signal來最終傳遞一些額外的數據。PyQT將λ函數連接到信號

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 

我希望這是有道理的 - 有沒有人有任何想法?感謝您的任何建議! 乾杯 戴夫

回答

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()信號的問題,因爲它沒有傳遞參數來替換默認值。

+0

真棒謝謝你,那曾經工作過!謝謝你解釋! –

+0

加上我,你怎麼知道參數被覆蓋? – user1767754

+0

@ 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_()) 
+0

嘿,謝謝!我還沒有設法通過這個,但今天晚些時候會有希望! –