Seite 1 von 1
Transparentes Fenster im vordergrund, unsichtbar für Maus
Verfasst: 21. März 2006 14:30
von drzoom
Hallo
Weiss jemand wie ich mit Qt4 ein Fenster für die Maus transparent machen kann (Windows).
Ich nehm das AnalogClock Beispiel von Qt4. Dort setze ich setWindowOpacity(0.2); zusätzlich im Konstruktor.
Jetzt möchte ich aber, dass wenn ich auf dem Fenster die Maus bewege, oder klicke, dass diese Messsages _durch_ das fenster hindurch auf das unterliegende fenster gehen. Also wenn ich hinter der Uhr z.B. ein Explorer fenster habe, kann ich dort dateien ganz normal auswählen, als ob die Uhr gar nicht da wäre.
Wie mache ich das?
Gruss
Tobias
Verfasst: 21. März 2006 15:25
von Esleborn
wenn es nicht auch für die "Ansicht" durchsichtig sein soll, wie wär es wenn du folgende Events überlädst, so dass sie nichts tun..
Code: Alles auswählen
virtual void mouseDoubleClickEvent ( QMouseEvent * event )
virtual void mousePressEvent ( QMouseEvent * event )
virtual void mouseReleaseEvent ( QMouseEvent * event )
denn der assistant sagt:
A mouse event contains a special accept flag that indicates whether the receiver wants the event. You should call ignore() if the mouse event is not handled by your widget. A mouse event is propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it.
Verfasst: 21. März 2006 15:31
von drzoom
Das würde nur die Events verhindern, aber nicht an die nächste Applikation weitergeben. Innerhalb eines Fensters funktioniert das, ich möchte die Transparenz aber Applikationsübergreifend:
Z-Order:
1. MyApp
2. Explorer
Wenn ich im Bereich von MyApp z.B. Klicke mit der Maus, soll eigentlich der Explorer die Message bekommen. Das Obwohl die Uhr sichtbar ist.
Also setMask ist auch keine Lösung, da die nicht maskierten Bereiche nicht sichtbar sind.
Gruss
Tobias
Verfasst: 21. März 2006 15:38
von macman
Deine Z-Order muß umgekehrt sein. Du kannst nicht deine MouseEvents an andere Apps weiter geben, denn Du weißt ja nicht welche App darunter liegt. Einzige Möglichkeit, die andere App muss vorne sein, aber deine App soll trotzdem sichtbar sein. Keine Ahnung ob es sowas wie alwaysOnTop bei Qt gibt, aber machbar ist es.
Verfasst: 21. März 2006 16:12
von drzoom
Hier das Beispiel mit der Uhr. Jetzt fehlt nur noch, dass wenn ich mit der Maus auf der Uhr klicke nicht die Uhr, sondern das dahinterliegende Fenster die Message bekommt.
Gruss
Tobias
Lösung
Verfasst: 18. Juni 2006 01:37
von Volker
Hi,
hab gerade dein Code runtergeladen und ein wenig rumprobiert. Zu mindest unter Windows hab ich eine Lösung:
In der Resize Methode hab ich folgenden Code hinzugefügt:
Code: Alles auswählen
int exstyle = GetWindowLong(winId(), GWL_EXSTYLE);
exstyle |= WS_EX_TRANSPARENT;
SetWindowLong(winId(), GWL_EXSTYLE, exstyle);
Somit ergibt sich folgendes:
Code: Alles auswählen
void AnalogClock::resizeEvent(QResizeEvent *event)
{
int side = qMin(width(), height());
QRegion maskedRegion(width()/2 - side/2, height()/2 - side/2, side, side,
QRegion::Ellipse);
setMask(maskedRegion);
int exstyle = GetWindowLong(winId(), GWL_EXSTYLE);
exstyle |= WS_EX_TRANSPARENT;
SetWindowLong(winId(), GWL_EXSTYLE, exstyle);
}
Damit erziehlst du zu mindest unter Windows den gewünschten Effekt. (Getestet unter Windows XP)
Verfasst: 19. Juni 2006 09:58
von drzoom
Danke für deine Hilfe.
Mittlerweile bin ich genau auf das selbe Resultat gekommen. Ich hab den code jedoch direkt im Konstruktor eingefügt:
Code: Alles auswählen
Clock::Clock( QWidget* parent )
: QWidget( parent, Qt::SplashScreen | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint )
{
setWindowTitle( APP_NAME " - " COMPANY " - V" VERSION );
setWindowOpacity( 0.5 );
resize( 100, 100 );
// (...)
SetWindowLong( winId(), GWL_EXSTYLE, GetWindowLong( winId(), GWL_EXSTYLE ) | WS_EX_TRANSPARENT );
}
Gleich noch mit den passenden Argumenten für das QWidget.
Tobias