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.
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:
Was verständlich ist, da das Ereignis direkt an das empfangende Objekt übergeben wird.
Ä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?
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
:
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:
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.
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.
Und anstelle der Instanz von QApplication verwenden wir die Instanz unserer Unterklasse.
%Vor%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.
Tags und Links qt events pyqt event-propagation