Overlay-Effekt fuer Touch-Applikation

Alles rund um die Programmierung mit Qt
Antworten
sting73
Beiträge: 7
Registriert: 9. April 2009 22:05

Overlay-Effekt fuer Touch-Applikation

Beitrag von sting73 »

Hallo zusammen,

ich habe eine Applikation geschrieben, welche über einen Touch-Panel gesteuert wird. Um dem Benutzer den "Druckpunkt" sichtbar zu machen würde ich gerne an die Stelle an welcher der Klick erkannt wurde einen transparenten, ausgefüllten hellen Kreis legen (diesen eventuell langsam ausblenden). Meine Idee war, über die komplette GUI ein einziges QWidget zu legen welches das mousePressEvent(...) verarbeitet, einen transparenten ausgefüllten Kreis zeichnet und dann das Event an die darunterliegenden Widgets weiterleitet. Das mit dem transparenten Zeichnen über die anderen Widgets funktioniert - was nicht funktioniert, ist das Weiterleiten des Events an die darunterliegenden Buttons...

Wie kann ich ein mousePressEvent(...) welches in einer von QWidget abgeleiteten Klasse verarbeitet wird an die überlagerten Widgets weiterleiten?

Bräuchte diesbezüglich dringend Hilfe.

Vielen Dank!!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Ich würde mal mit einem eventFilter bei QCoreApplication ansetzen.
sting73
Beiträge: 7
Registriert: 9. April 2009 22:05

Beitrag von sting73 »

Hallo,

ersteinmal Danke für den Tip. Der Eventfilter in QApplication hat mich schon ein wenig weiter gebracht. Leider funktioniert das Durchreichen der Nachrichten immer noch nicht vollständig. Ich vermute aber es gibt einen Trick die letzte Hürde auch noch zu nehmen.

Ich habe in meiner Klasse CTouchWidget einen Eventfilter installiert:

(Konstruktor)

Code: Alles auswählen

...
 m_pApp = (QApplication*) QApplication::instance();
 m_pApp->installEventFilter(this);
...
In meiner Filter-Methode mach ich nun folgendes:

Code: Alles auswählen

if(pTarget==this){ // Touch class events 
      if(pEvent->type() == QEvent::MouseButtonPress){
            this->hide();
            this->initWave(); // start overlay effect
            pEvent->ignore();
            return m_pApp->eventFilter(pTarget,pEvent);
     }
 }
Nun wird das MouseButtonPress-Event an die darunterliegenden Widgets weitergeleitet wie gewollt. Leider kommt nun aber kein MouseButtonRelease-Event im Eventfilter beim Loslassen der Taste an. Somit bleibt auch ein darunterliegender Button immer im "gedrückt"-Modus. Hat jemand eine Idee woran das liegen kann? Ich verstehe nicht warum das Release-Event nach dem hide() aufruf nicht mehr generiert wird... (es kommt auch nicht im Event-Filter an :-( )

Würde mich über Anregungen freuen - habe wieder mal keine Idee mehr wo ich ansetzen soll!

Gruß,

sting73
Dateianhänge
Effekt nach dem Drücken und Loslassen der Maus.
Effekt nach dem Drücken und Loslassen der Maus.
overlay_effekt.JPG (5.63 KiB) 2695 mal betrachtet
Zuletzt geändert von sting73 am 20. April 2009 19:20, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Zeig mal initWave(). Kann es sein, dass das - kein Ende hat?
Kommen denn überhaupt noch events an? Also kannst du noch klicken, und der Effekt startet an einer anderen Position? Mach mal in deinen Test einen zweiten Button, ob der dann vllt. noch events abgibt/abkriegt.
sting73
Beiträge: 7
Registriert: 9. April 2009 22:05

Beitrag von sting73 »

Hallo,

mehrfach klicken funktioniert (kein blockierender Aufruf). Die Animation mit den Kreisen erfolgt asynchron in einem anderen Thread (generiert Repaint-Events für das Widget ). Selbst wenn ich diesen Aufruf weglasse verhält sich der darunterliegende Button so. Habe auch Debug-Ausgaben in die Event-Filter-Methode eingebaut. Folgende Events kommen:

Widget: MainWindow(0x22fdc0) Type: QMouseEvent(MouseButtonPress, 1, 1, 0)
Widget: MainWindow(0x22fdc0) Type: QEvent(0x3e59c8, type = 76)
Widget: CAbkTouchWidget(0x5170c08) Type: QShowEvent(0x22d370)
Widget: QPushButton(0x3ea008) Type: QLeaveEvent(0x22d120)
Widget: CAbkTouchWidget(0x5170c08) Type: QEnterEvent(0x22d100)
Widget: CAbkTouchWidget(0x5170c08) Type: QMouseEvent(MouseMove, 0, 1, 0)
Widget: MainWindow(0x22fdc0) Type: QMouseEvent(MouseMove, 0, 1, 0)
Widget: CAbkTouchWidget(0x5170c08) Type: QShowToParentEvent(0x22d420)
Widget: MainWindow(0x22fdc0) Type: QEvent(0x3eb1c8, type = 76)
Widget: CAbkTouchWidget(0x5170c08) Type: QMouseEvent(MouseMove, 0, 0, 0)
Widget: CAbkTouchWidget(0x5170c08) Type: QMouseEvent(MouseMove, 0, 0, 0)
Widget: CAbkTouchWidget(0x5170c08) Type: QLeaveEvent(0x22bfdc)
Widget: MainWindow(0x22fdc0) Type: QMouseEvent(MouseMove, 0, 0, 0)

(Repaint Nachrichten habe ich rausgefiltert um das ganze etwas übersichtlicher zu gestalten)

Man kann das ganze auch recht einfach nachstellen. Button mit absoluter Positionierung erstellen. Zweiten Button (oder Widget) darüberlegen (halb überdecken und eventuell halb transparentes Rechteck zeichnen) und den Eventfilter in das zweite Widget einfügen (siehe oben). Das Mouse-Press Event wird an den zweiten Button weitergeleitet. Danach kommt aber kein Release-Event mehr. Drückt man in einen nicht überlagerten Bereich des ersten Buttons kommt der Button auch wieder hoch und man kann das ganze Spiel wieder von vorne betreiben.

Gruß,

sting73
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Aiaia, sach ma, das ist doch ein Widget, das sich über das andere Fenster legt, oder? Dann liegt es doch nahe, dass DIESES Widget den Release erhält, da es über dem anderen liegt und Focus hat.
Was passiert, wenn du die Animation (und damit ja auch das Überlagern) mit einem gewissen Timeout (testweise mach mal 1000 msec) anfängst, dann solltest du doch das ReleaseEvent bekommen.

Andernfalls merkst du dir einfach das Widget und das Event, und sendest selber das entsprechende Event, wenn die ANimation abgeschlossen ist.

Sollte das alles gar nicht helfen, häng einfach deinen aktuellen Test-Source komplett kompilierbar als Zip hier an, dann kann man bissl mehr experimentieren ;)

Grüße
Franz
sting73
Beiträge: 7
Registriert: 9. April 2009 22:05

Beitrag von sting73 »

Hallo,

so, habe mal "quick and dirty" eine kleines Projekt gebastelt in dem man das Problem schnell erkennt (ohne Animation). Ziel ist es, die Nachrichten vom oberen Widget an die darunterliegenden weiterzuleiten.
Drückt man ausserhalb des Kreises (Button-Widget) ist alles OK. Drückt man auf den Kreis (Top-Widget), geht das Pressed-Event an den Button - auch gut. Leider kommt jetzt aber jetzt kein MouseButtonRelease-Event mehr - der Button bleibt unten.

Danke schon mal an alle für die Hilfe!!

Gruß,

Denis
Dateianhänge
OverlayDemo.zip
(133.11 KiB) 48-mal heruntergeladen
overlay_effekt_demo.JPG
overlay_effekt_demo.JPG (3.82 KiB) 2680 mal betrachtet
Antworten