Weiterleiten von benutzerdefiniertem QEvent an das übergeordnete Widget in Qt / PyQt

8

Fist, Entschuldigung für die Länge der Frage.

Ich versuche, benutzerdefiniertes Qt-Ereignis von untergeordneten Widgets zu einem übergeordneten übergeordneten Widget zu propagieren, um eine Aktion basierend auf dem Ereignistyp auszulösen, anstatt Signale zu verknüpfen.

Qt docs schlägt vor, dass jedes mit postEvent() gepostete Ereignis mit den Methoden accept() und ignore() propagiert werden kann (dh jede QEvent Unterklasse).

Ich habe versucht, customEvents method anstelle von events außer Kraft zu setzen, aber ohne Erfolg.

Python

Ich habe das in Python mit PyQt4 versucht (Qt-Version ist 4.6).

%Vor%

In diesem Beispiel würde Bar.someEventHandler() nur dann auslösen, wenn das Ereignis mit self.parent() als erstes Argument wie folgt gepostet wurde:

%Vor%

Was verständlich ist, da das Ereignis direkt an das empfangende Objekt übergeben wird.

C ++

Ähnliches Beispiel in C ++:

foobar.h

%Vor%

foobar.cpp

%Vor%

main.cpp

%Vor%

Wie in Python funktioniert das nur, wenn das Ereignis direkt an ein Objekt übergeben wird.

%Vor%

Vielleicht habe ich den Punkt verpasst, ist es möglich, dass nur Key und Mouse Ereignisse nach oben propagiert werden?

    
Davor Lucic 05.07.2010, 15:03
quelle

3 Antworten

16

Ich habe einige Zeit damit verbracht, die Qt-Quelle zu durchsuchen, um Ihre Frage zu beantworten, und was ich schließlich herausgefunden habe, ist Folgendes: Die Weitergabe von Ereignissen an übergeordnete Widgets erfolgt durch QApplication::notify , im Grunde eine lange switch -Anweisung mit allen möglichen Ereignissen. Zum Beispiel für QEvent::WhatsThisClicked :

%Vor%

Nun der hervorstechende Punkt: Dies wird nicht für benutzerdefinierte Ereignisse (und viele andere explizit behandelte Standard-Qt-Ereignisse) ausgeführt, da die default -Klausel lautet:

%Vor%

Und notify_helper verbreitet keine Ereignisse. Also, meine Antwort ist: scheinbar benutzerdefinierte Ereignisse werden nicht zu übergeordneten Widgets weitergegeben, Sie müssen es selbst tun (oder besser: QApplication::notify überschreiben (es ist ein virtuelles öffentliches Mitglied) und fügen Sie Ereignisausbreitung für Ihre Veranstaltung (en) ).

Ich hoffe, das hilft.

    
Greg S 06.07.2010, 08:06
quelle
5

Re-Implementation von QApplication.notify in Python, die benutzerdefinierte Ereignisse propagieren würde.

In Qt notfy_helper stellt sicher, dass die Ereignisfilter aufgerufen werden (sowohl QApplications als auch Empfänger), aber ich habe das übersprungen, da ich sie nicht brauche und notfy_helper ist privates Mitglied.

%Vor%

Und anstelle der Instanz von QApplication verwenden wir die Instanz unserer Unterklasse.

%Vor%     
Davor Lucic 07.07.2010 11:02
quelle
1

Als Alternative zu der Antwort von rebus implementiert dieser Ausschnitt die manuelle Propagierung eines Ereignisses:

%Vor%

Beachten Sie, dass sendEvent verwendet wird und daher für den Thread aufgerufen werden muss, auf dem das Zielobjekt vorhanden ist. Diese Einschränkung kann mit mehr Indirektion umgangen werden.

Beachten Sie, dass Sie _manual_propagate / anstelle von / sendEvent selbst aufrufen müssen. Dies ist eine "weniger automatische" Version der Rebus-Technik.

Da diese Version außerdem sendEvent verwendet, werden Ereignisfilter für Objekte ordnungsgemäß aufgerufen.

Der relevante Grund, warum benutzerdefinierte Ereignisse zumindest in Qt 4.8 nicht verbreitet werden, ist folgendes:

%Vor%

Das heißt, QObject::event ruft eine andere Methode auf, wenn ein benutzerdefiniertes Ereignis empfangen wird, und dann break s aus der switch -Anweisung und führt return true;' aus. Dieser return true signalisiert dem Aufrufer (normalerweise QCoreApplication::notify , mit dem das Ereignis behandelt wurde.

    
EB. 02.05.2013 16:51
quelle

Tags und Links