2013-01-05 36 views
5

Tôi đang mắc kẹt với vấn đề sau. Tôi đang cố gắng để kết nối một chức năng lambda với một tín hiệu cho đi qua một số dữ liệu phụ cuối cùng.PyQT Kết nối hàm lambda với 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 

Khi tôi chạy createTimeComboBox(), tôi nhận được lỗi này:

TypeError: 'int' object is not callable 

Thay đổi

self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),cmd) 

để

self.connect(timeComboBox, SIGNAL("currentIndexChanged(int)"),self.test) 

hoạt động tốt, nhưng tôi muốn để có thể vượt qua số slotCopy cũng thay đổi, vì vậy giả sử rằng tôi cần sử dụng phương pháp lambda.

Tôi đã thực hiện việc này trước đây với tín hiệu clicked() của và hoạt động tốt.

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 

Tôi hy vọng điều này có ý nghĩa - có ai có ý tưởng nào không? Cảm ơn mọi lời đề nghị! Cheers Dave

Trả lời

5

bạn lambda chấp nhận thông số (func):

lambda func=self.test:func() 

Mặc dù tham số có mặc định, tham số này sẽ được thay thế nếu tham số được truyền. Nhìn vào tín hiệu, currentIndexChanged(int), cho thấy tín hiệu sẽ truyền một tham số nguyên. func sẽ là số nguyên đến từ currentIndexChanged. Sau đó, làm func() sẽ có hiệu quả cố gắng để gọi một đối tượng số nguyên mà rõ ràng là không hợp pháp (như lỗi chỉ ra)

Bạn cần một tham số trong lambda để "bắt" các tham số truyền của bạn mà không trọng tham số func:

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

Nhân tiện, phương pháp test của bạn sẽ có tham số, vì vậy bạn không thể chỉ thực hiện func().

Bạn không gặp sự cố đó với tín hiệu clicked() vì nó không chuyển thông số để thay thế giá trị mặc định.

+0

Tuyệt vời cảm ơn bạn, đã làm việc một điều trị! Cảm ơn bạn đã giải thích điều đó! –

+0

Cộng với tôi, làm cách nào bạn biết Thông số bị ghi đè? – user1767754

+0

@ user1767754 bằng cách tín hiệu hoạt động trong Qt. Các khe có thể có cùng hoặc ít đối số hơn và các đối số bổ sung sẽ bị bỏ qua. Nhưng những cái còn lại sẽ được thông qua. Nó không quan trọng nếu bạn có một mặc định cho đối số đó hay không. Nếu một tín hiệu vượt qua một đối số, khe sẽ nhận được nó nếu nó có thể. – Avaris

3

Xem nếu công trình này dành cho bạn:

timeComboBox.currentIndexChanged.connect(self.test) 

Dưới đây là một ví dụ làm việc nhỏ, thể hiện kết nối tín hiệu phong cách/khe mới có và không có 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_()) 
+0

Xin chào, cảm ơn vì điều này! Tôi đã không quản lý để đi qua này được nêu ra, nhưng sẽ nhận được xung quanh nó sau này hy vọng ngày hôm nay! –

Các vấn đề liên quan