2009-06-02 16 views
27

Ho un menu sulla barra delle applicazioni che quando si fa clic viene collegato a uno slot che riceve l'evento trigger. Ora il problema è che voglio sapere quale voce del menu è stata cliccata, ma non so come inviare quella informazione alla funzione connessa. Qui è il usati per collegare l'azione alla funzione:PyQt invio parametro allo slot quando ci si collega a un segnale

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

So che alcuni eventi restituiscono un valore, ma ha innescato() non. Quindi, come faccio a fare in modo che questo accada? Devo fare il mio segnale?

risposta

40

Utilizzare un lambda

Ecco un esempio dalla PyQt book:

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

Tra l'altro, è anche possibile utilizzare functools.partial, ma trovo il metodo lambda più semplice e chiaro.

+0

Ehi, grazie mille! Totalmente mi ha salvato un sacco di frustrazione. Probabilmente dovrei prendere possesso di quel libro ... – johannix

+1

Dovresti davvero - è un libro molto buono. –

+0

risposta impressionante, questo è esattamente quello che stavo cercando – Bedros

0

In generale, è necessario che ciascuna voce di menu sia collegata a uno slot diverso e che ogni slot gestisca la funzionalità solo per la propria voce di menu. Ad esempio, se hai voci di menu come "salva", "chiudi", "apri", dovresti creare uno slot separato per ciascuna, non provare ad avere un singolo slot con un'istruzione case.

Se non si desidera eseguire questa operazione, è possibile utilizzare la funzione QObject::sender() per ottenere un puntatore al mittente (ad esempio: l'oggetto che ha emesso il segnale). Mi piacerebbe sentire un po 'di più su quello che stai cercando di realizzare, però.

+3

L'OP sta chiedendo un bisogno perfettamente legittimo. A volte molte voci di menu sono generate automaticamente (o solo molto simili) e dovrebbero fare riferimento allo stesso slot. C'è un modo standard per ottenere questo in PyQt che è raccomandato nel libro e nei tutorial. –

7

Come già accennato here è possibile utilizzare la funzione lambda per passare argomenti aggiuntivi al metodo che si desidera eseguire.

In questo esempio è possibile passare una stringa obj alla funzione AddControl() richiamata quando si preme il pulsante.

# 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 

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

3

uso functools.partial

altrimenti troverete non è possibile passare gli argomenti in modo dinamico quando lo script è in esecuzione, se si utilizza lambda.

+2

Cura di eseguire il backup con alcune prove? – ekhumoro

+0

Si può benissimo passare argomenti dinamicamente in un lambda creato, come lambda (come le normali funzioni 'def''ed) sono le chiusure e quindi catturano le associazioni dal loro ambito di chiusura. (Sì, ciò implica anche che come terza opzione potresti usare una funzione localmente def. _e_ passare dinamicamente i parametri ad essa.) Inoltre, non dimenticare che puoi usare gli argomenti predefiniti per passare valori dinamici a _both_ di loro . Tuttavia, detto questo, personalmente preferisco 'functools.anche parziale, il mio stesso motivo è che "sembra" più leggero di un "lambda" (senza pretendere che sia effettivamente). – blubberdiblub

0

Vorrei anche aggiungere che è possibile utilizzare il metodo sender se è solo necessario sapere quale widget ha inviato il segnale. Ad esempio:

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