QtCore.QObject.connect en un bucle solo afecta a la última instancia

Tengo un bucle. QCheckBox un QCheckBox y lo puse en una celda QTableWidget , y todo está bien. En cada paso del ciclo he llamado una función de connect , para myslot SLOT, pero solo se aplica la última instancia de QCheckBox . Busqué en Google y he descubierto que muchas personas tienen mi problema. He aplicado sus soluciones, pero mi problema permanece.

 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) 

Nota: mi función de connect devuelve True .

¿Cómo crear la función de connect en un bucle que enumera todas las instances ?

Tengo el mismo problema, debe usar functools.partial como:

 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) 

Por supuesto, argX debe establecer su nombre real de su argumento del nombre de su función.

Coloque la variable de bucle en un argumento predeterminado, como este:

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

Esto le dará a cada lambda su propia copia local de la variable de instance .

EDITAR

Aquí hay un script simple que demuestra cómo usar los argumentos lambda predeterminados:

 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_()) 

El problema es que está creando una función usando lambda donde algunas de las variables dentro de la función no se pasan como argumentos a la función. Cuando se ejecuta la función lambda, cuando se emite la señal, utiliza el valor de esas variables (como instance ) en ese momento en el tiempo. Para que quede claro, cada función lambda que usted hace usa el valor de la instance en tiempo de ejecución, en lugar de definir el tiempo. Por lo tanto, instance solo contiene una referencia al objeto utilizado en la última iteración de nuestro ciclo, lo que explica el comportamiento que estás viendo.

Parte de la información útil se puede encontrar aquí (lea también los comentarios) http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot/

De los comentarios del enlace de arriba:

Lo que puedes hacer es tener otra función generar la lambda, es decir algo como:

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

Y en la conexión, llame a make_callback(i) . Entonces se crea una lambda diferente para cada iteración.

Por lo tanto, desearía generalizar esto y pasar cosas como instance a la función make_callback y luego colocar su definición lambda dentro de la función make_callback . Daría un ejemplo claro de esto, pero como dice la otra respuesta, su formateo parece haberse desordenado mucho en su pregunta y probablemente me equivocaría en su aplicación específica. Si no estás siguiendo lo que dije, haz el código en tu pregunta más clara y ¡intentaré crear un ejemplo!