2009-06-02 8 views
27

Tengo un menú en la barra de tareas que cuando se hace clic está conectado a una ranura que recibe el evento de activación. Ahora el problema es que quiero saber en qué elemento del menú se hizo clic, pero no sé cómo enviar esa información a la función conectada. Aquí está la utiliza para conectar la acción de la función:PyQt enviando el parámetro a la ranura cuando se conecta a una señal

QtCore.QObject.connect(menuAction, 'triggered()', menuClickedFunc) 

Sé que algunos eventos devuelven un valor, pero provocó() no. Entonces, ¿cómo hago que esto suceda? ¿Debo hacer mi propia señal?

Respuesta

40

Utilice un lambda

He aquí un ejemplo de la PyQt book:

self.connect(button3, SIGNAL("clicked()"), 
    lambda who="Three": self.anyButton(who)) 

Por cierto, también se puede utilizar functools.partial, pero me parece el método más sencillo y claro lambda.

+0

¡Hola, muchas gracias! Totalmente me salvó MUCHAS frustración. Probablemente debería obtener ese libro ... – johannix

+1

Realmente deberías - es un libro muy bueno. –

+0

respuesta increíble, esto es exactamente lo que estaba buscando – Bedros

0

En general, debe tener cada elemento de menú conectado a una ranura diferente, y que cada ranura maneje la funcionalidad solo para su propio elemento de menú. Por ejemplo, si tiene elementos de menú como "guardar", "cerrar", "abrir", debe hacer un espacio separado para cada uno, no tratar de tener un solo espacio con una declaración de caso en él.

Si no desea hacerlo de esa manera, puede usar la función QObject::sender() para obtener un puntero al remitente (es decir, el objeto que emitió la señal). Sin embargo, me gustaría escuchar un poco más sobre lo que estás tratando de lograr.

+3

El OP pregunta por una necesidad perfectamente legítima. A veces, muchos elementos del menú se generan automáticamente (o son muy similares) y deben referirse a la misma ranura. Hay una forma estándar de lograr esto en PyQt que se recomienda en el libro y en tutoriales. –

7

Como ya se mencionó here puede usar la función lambda para pasar argumentos adicionales al método que desea ejecutar.

En este ejemplo, puede pasar un string obj a la función AddControl() invocada cuando se presiona el botón.

# Create the build button with its caption 
self.build_button = QPushButton('&Build Greeting', self) 
# Connect the button's clicked signal to AddControl 
self.build_button.clicked.connect(lambda: self.AddControl('fooData')) 
def AddControl(self, name): 
    print name 

Fuente: snip2code - Using Lambda Function To Pass Extra Argument in PyQt4

3

uso functools.partial

de lo contrario se encuentra que no puede pasar argumentos de forma dinámica cuando se ejecuta un script, si utiliza lambda.

+2

¿Cuidar para respaldar esto con alguna evidencia? – ekhumoro

+0

Puede pasar argumentos dinámicamente a una lambda creada, ya que las lambdas (como las funciones normales 'def''ed) son cierres y, por lo tanto, capturan las vinculaciones de su ámbito adjunto. (Sí, eso también implica que, como tercera opción, podría usar una función 'definida localmente _y_ pasar parámetros dinámicamente a ella.) Además, no olvide que puede usar argumentos predeterminados para pasar valores dinámicos a _ambos_ de ellos . Sin embargo, habiendo dicho eso, personalmente prefiero 'functools.parcial' también, mi propia razón es que "se siente" más ligero que una 'lambda' (sin hacer una afirmación de que realmente lo es). – blubberdiblub

0

También me gustaría agregar que puede usar el método sender si solo necesita averiguar qué widget envió la señal. Por ejemplo:

def menuClickedFunc(self): 
    # The sender object: 
    sender = self.sender() 
    # The sender object's name: 
    senderName = sender.objectName() 
    print senderName 
Cuestiones relacionadas