2013-10-22 4 views
1

루프가 있습니다. QCheckBox을 작성하여 QTableWidget 셀에 넣으면 모든 것이 OK입니다. 루프의 각 단계에서 나는 connect 함수를 호출했는데, 마지막으로 QCheckBox 인스턴스 만 적용됩니다. 나는 많은 것을 봤고 많은 사람들이 내 문제를 안고 있음을 알았다. 나는 그들의 해결책을 적용했지만 내 문제가 남아있다.루프의 QtCore.QObject.connect는 마지막 인스턴스에만 영향을줍니다.

for row in xrange(len(uniqueFields)): 
    instance = QtGui.QCheckBox(uniqueFields[row], findInstance.tableWidget) 
    print QtCore.QObject.connect(instance, 
     QtCore.SIGNAL(_fromUtf8("stateChanged (int)")), 
     lambda: findInstance.projectsInstance.myslot(
        "TWCH", findInstance, instance.text(), 
        instance.checkState(), instance)) 
    findInstance.tableWidget.setRowCount(findInstance.tableWidget.rowCount() + 1) 
    findInstance.tableWidget.setCellWidget(row, 0, instance) 

참고 :connect 함수 반환 True.

instances을 모두 열거하는 루프에서 connect 함수를 만드는 방법은 무엇입니까?

답변

1

나는 같은 문제가, 당신이 사용해야가 functools.partial 같은 :

for key, val in a_DICT_THAT_YOU_STORED_YOUR_OBJECTS_AND_STRINGS: 
    obj = partial( findInstance.projectsInstance.myslot,arg1="TWCH",arg2=self,arg3=key,arg4=val.checkState()) 
    QtCore.QObject.connect(val, QtCore.SIGNAL(_fromUtf8("stateChanged (int)")), obj) 

물론 argX는 함수 이름의 실제 인수로 설정해야합니다.

0

lambda을 사용하여 함수를 작성하는 중입니다. 여기서 함수의 일부 변수는 함수의 인수로 전달되지 않습니다. 람다 함수가 실행될 때, 신호가 방출 될 때, 그 순간에 그 변수의 값 (예 : instance)을 사용합니다. 분명히하기 위해, 모든 람다 함수는 시간을 정의하는 대신 런타임에 instance의 값을 사용합니다. 따라서 instance은 루프의 마지막 반복에서 사용 된 객체에 대한 참조 만 보유하고 있으며 이는 사용자가보고있는 동작을 설명합니다. 즉,

은 무엇 당신이 할 수있는 것은 또 다른 기능은 람다를 생성 가지고있다 을 :

몇 가지 유용한 정보는 위의 링크의 코멘트에서 http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot/

(너무 코멘트 읽기) 여기에서 찾을 수 있습니다 다음과 같이 입력하십시오 :

def make_callback(param): 
     return lambda: self.on_button(param) 

make_callback(i)을 호출하십시오. 그런 다음 각 반복에 대해 다른 람다가 입니다.

그래서 당신이 일반화하고 make_callback 기능에 instance 같은 것들을 전달하고 make_callback 기능을 내부에 lambda 정의를 배치 할 것입니다. 나는 이것에 대한 명확한 예를 제시 할 것이지만, 다른 답변에서 말한 것처럼 당신의 포맷은 당신의 질문에 매우 엉망이되어서 당신의 특정 어플리케이션에 잘못 될 가능성이 있습니다. 내가 말한 것을 따르지 않는다면, 질문의 코드를 명확하게 만들고 예제를 만들자!

2

이 같은 기본 인수에 루프 변수를 넣어 :이 instance 변수의 각 lambda 자신의 로컬 복사본을 줄 것이다

lambda state, instance=instance: findInstance.projectsInstance.myslot(
    "TWCH", findInstance, instance.text(), instance.checkState(), instance) 

.여기에 편집

기본 람다 인수를 사용하는 방법을 보여주는 간단한 스크립트입니다 :

from PyQt4 import QtGui 

class Window(QtGui.QWidget): 
    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     layout = QtGui.QVBoxLayout(self) 
     for index in range(4): 
      instance = QtGui.QCheckBox('Checkbox(%d)' % index, self) 
      instance.stateChanged.connect(
       lambda state, instance=instance: 
        self.mySlot(instance.text())) 
      layout.addWidget(instance) 

    def mySlot(self, text): 
     print('clicked: %s' % text) 


if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 
+0

신호가 방출 될 때 아무런 인수도 슬롯에 전달되지 않으므로 작동하지 않습니다. 인수없이 람다를 생성해야하지만 여전히 인스턴스의 자체 복사본이 있습니다. 따라서 람다를 만드는 함수를 사용하는 나의 대답 –

+0

@ three_pineapples. 그것은 완벽하게 잘 작동합니다 : 작동 예제에 대한 나의 업데이트 된 답변을 참조하십시오. 원래의 대답에서 설명했듯이, 기본 변수는 루프 변수를 캐시하는 데 사용되므로 클로저를 사용할 필요가 없습니다 (작동 할 수도 있음). – ekhumoro

+0

아, 죄송합니다, 나는 그것의'instance = instance' 부분을 건너 뛰었습니다 (단지'instance'를 읽었습니다). 귀하의 방법은 내 제안보다 훨씬 깨끗하고 내 코드에서 사용하기 시작할 것입니다. –

관련 문제