2009-06-02 11 views
27

Ich habe ein Taskleiste-Menü, das beim Anklicken mit einem Steckplatz verbunden ist, der das Trigger-Ereignis erhält. Nun ist das Problem, dass ich wissen möchte, welcher Menüpunkt angeklickt wurde, aber ich weiß nicht, wie ich diese Informationen an die Funktion senden soll, mit der ich verbunden bin. Hier wird die verwendet, um die Wirkung auf die Funktion zu verbinden:PyQt Senden von Parameter zu Steckplatz beim Verbinden mit einem Signal

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

Ich weiß, dass einige Ereignisse einen Wert zurückgeben, aber ausgelöst() nicht. Wie mache ich das möglich? Muss ich mein eigenes Signal geben?

Antwort

40

Verwenden Sie ein lambda

Hier ist ein Beispiel aus dem PyQt book:

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

By the way, können Sie auch functools.partial verwenden, aber ich finde die lambda Methode einfacher und übersichtlicher.

+0

Hey, vielen Dank! Ich habe total viel Frust gerettet. Ich sollte dieses Buch wahrscheinlich in die Finger bekommen ... – johannix

+1

Das solltest du wirklich - es ist ein sehr gutes Buch. –

+0

tolle Antwort, das ist genau das, was ich suchte – Bedros

0

Im Allgemeinen sollte jeder Menüeintrag mit einem anderen Steckplatz verbunden sein, und jeder Steckplatz muss die Funktionalität nur für seinen eigenen Menüeintrag übernehmen. Zum Beispiel, wenn Sie Menüpunkte wie "Speichern", "Schließen", "Öffnen" haben, sollten Sie für jeden einen separaten Slot anlegen, nicht versuchen, einen einzelnen Slot mit einer case-Anweisung darin zu haben.

Wenn Sie es nicht so machen möchten, können Sie die QObject::sender() Funktion verwenden, um einen Zeiger auf den Sender zu erhalten (dh: das Objekt, das das Signal ausgab). Ich würde gerne ein bisschen mehr darüber hören, was Sie erreichen wollen.

+3

Das OP fragt nach einem vollkommen legitimen Bedürfnis. Manchmal werden viele Menüpunkte automatisch generiert (oder nur sehr ähnlich) und sollten sich auf den gleichen Slot beziehen. Es gibt einen Standardweg, um dies in PyQt zu erreichen, der im Buch und in Tutorials empfohlen wird. –

7

Wie bereits erwähnt here können Sie die Lambda-Funktion verwenden, um zusätzliche Argumente an die Methode übergeben, die Sie ausführen möchten.

In diesem Beispiel können Sie eine Zeichenfolge obj an die Funktion AddControl() übergeben, die beim Drücken der Schaltfläche aufgerufen wird.

# 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 

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

3

Verwendung functools.partial

sonst werden Sie feststellen, Sie können nicht Argumente dynamisch übergeben, wenn Skript ausgeführt wird, wenn Sie Lambda verwenden.

+2

Möchten Sie dies mit einigen Beweisen untermauern? – ekhumoro

+0

Sehr gut können Sie Argumente dynamisch in ein erzeugtes Lambda übergeben, da Lambdas (wie normale 'def''ed-Funktionen) Verschlüsse sind und somit die Bindungen aus ihrem umschließenden Umfang erfassen. (Ja, das bedeutet auch, dass Sie als dritte Option eine lokale 'def''ed-Funktion verwenden können _und_ Parameter dynamisch an diese übergeben.) Vergessen Sie auch nicht, dass Sie Standardargumente verwenden können, um dynamische Werte an _both_ von ihnen zu übergeben . Allerdings bevorzuge ich 'functools '.teilweise auch, mein eigener Grund ist, dass es "leichter" fühlt als ein "Lambda" (ohne zu behaupten, dass es tatsächlich ist). – blubberdiblub

0

Ich möchte auch hinzufügen, dass Sie die sender Methode verwenden können, wenn Sie nur herausfinden müssen, welches Widget das Signal gesendet hat. Zum Beispiel:

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