Transparentes Fenster im vordergrund, unsichtbar für Maus

Alles rund um die Programmierung mit Qt
Antworten
drzoom
Beiträge: 4
Registriert: 21. März 2006 14:25

Transparentes Fenster im vordergrund, unsichtbar für Maus

Beitrag 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
Esleborn
Beiträge: 265
Registriert: 27. Januar 2005 01:23
Wohnort: Baden-Würtenberg
Kontaktdaten:

Beitrag 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.
Glaube an eine Lösung, nur dann kannst du auch eine finden.
drzoom
Beiträge: 4
Registriert: 21. März 2006 14:25

Beitrag 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
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag 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.
drzoom
Beiträge: 4
Registriert: 21. März 2006 14:25

Beitrag 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
Dateianhänge
TransparentClock.zip
Das Uhrbeispiel
(3.08 KiB) 166-mal heruntergeladen
Volker
Beiträge: 343
Registriert: 30. Juni 2005 05:27

Lösung

Beitrag 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)
drzoom
Beiträge: 4
Registriert: 21. März 2006 14:25

Beitrag 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
Antworten