[gelöst] QWidgtet transparent , QT 4.6

Alles rund um die Programmierung mit Qt
Antworten
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

[gelöst] QWidgtet transparent , QT 4.6

Beitrag von chris_g »

Hallo,

ich versuche seit Tagen ein Widget transparent zu setzen und fand dazu ca. 50 Anleitungen in verschiedenen Foren und Maillinglists... Nichts davon funktioniert.

Es geht um einen VideoController der unter oder auf einem Video sitzt (libvlc). Nach den VLC-QT4 Quellen sollte das gehen (siehe VLC FullscreenControllerWidget).

Der Controller selbst hat Slider, Labels, Pixmaps als Children.

Ich versuchte es mit Masken, Paintern, anderen Beispielen... und aktuell mit:

Code: Alles auswählen

   this->setAutoFillBackground(true);
   this->setBackgroundRole(QPalette::NoRole);
   this->setAttribute(Qt::WA_NoSystemBackground, true);
   this->setWindowOpacity(0.5);
Wir nutzen QT 4.6.

Kann jemand, der das mittlerweil hinbekommen hat hier ein Beispiel posten?


Danke
cg
Zuletzt geändert von chris_g am 11. Dezember 2009 11:24, insgesamt 2-mal geändert.
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

Manchmal ist die Doku besser als 100 Foren...

Die Lösung:

setWindowOpacity() greift scheinbar nur bei Top-Level Widgets, was bedeutet, dass das ParentWidget des Controllers jetzt QApp ist!

Dann ist das Widget aber in einem Systemfenster, aber wie das aussieht kann man beeinflussen:

Code: Alles auswählen

setWindowModality(Qt::ApplicationModal); // Oder Qt::WindowModal sonst verschwindet das Fenster wenn man auf die Hauptanwendung klickt. Sehr schlecht bei Fullscreen....
	
setWindowFlags(Qt::FramelessWindowHint); // So hat das Widget keinen Fensterrahmen.

setWindowOpacity(0.5);  // Und dann klappts auch mit dem Alphawert
Umgesetzt in QT 4.6.


EDIT:

Ok so einfach wär schön gewesen. Macht man es auf diese Weise sollte das Fesnter Modal sein sonst verschwindet es wie gesagt. Dann kann man aber nichts anderes mehr anklicken. So soll ja Modalität auch sein.

Ich habe festgestellt, dass die Transparenz nur funktioniert, wenn das Widget, wie beschrieben, ein TOP-LEVEL Widget ist (QApp als parent oder kein parent). Gibt man ein ParentWidget an, funktioniert die Transparenz nur OHNE setWindowFlags(Qt::FramelessWindowHint).

Es gibt aber eine Möglichkeit beides zu haben. Ein parentwidget UND ein Rahmenloses Fenster. Im Konstruktor des Widget muss folgende Eigenschaft gesetzt werden:

Code: Alles auswählen

setWindowFlags(Qt::SplashScreen);
Damit hat kann das Widget ein parent haben, verschwindet also nicht wenn man daneben klickt, es hat keinen Rahmen und man kann den Alphawert ändern.

[/quote]
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

im stylesheet einfach background: transparent; oder?
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

Das ging bei mir nicht.
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Sollte es aber ;-)
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

Einiges von dem was gehen "sollte" ging oder geht leider nicht.
Da ich das Widget mit einem Timer ausblende, macht es aus meiner Sicht auch mehr Sinn es mit setWindowOpacity zu machen als jede 100ste Millisekunde einen neuen Sytelsheet zu setzen.
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Ok.... so gesehen hast natürlich recht.... allerdings kannst zum ausblenden in 100ms auch setVisible auf false setzen
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

Ne ich blende über in 1 Sekunde aus... Das wären dann 10 mal in einer Sekunde den Stylesheet neu setzen.
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

@ AuE: QWidget{ background: transparent; } geht auch bei mir. Allerdings nur für den "background". Meine Beschreibung zeigt wie man das Widget samt den Buttons drauf transparent macht.
Aber danke für den Tipp! Jetzt müssen Anfang und Ende des Controllers nicht unbedingt rechteckig sein...
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Wenn du Control anpassen willst wäre in dem Fall allerdings dann border-image die richtige Wahl!
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

Die custom Buttons und Slider sind mit CSS und wie Du sagst Border-Image gebaut. Das pass soweit.

Z.B. so für den Stop-Button

Code: Alles auswählen

//### Stop Button
	stopButton = new ControllerButton();	// Abgeleitet von QPushButton
    stopButton->setSizePolicy( sizePolicy );
    stopButton->setFixedSize( QSize( 30, 30 ) );
    stopButton->setIconSize( QSize( 30, 30 ) );

	styleString = QString("QPushButton{border-image: url(").append(Globals::getImagePath()).append("buttonStop_up.png);}");
	styleString.append("QPushButton:!hover{border-image: url(").append(Globals::getImagePath()).append("buttonStop_up.png);}");
	styleString.append("QPushButton:hover{border-image: url(").append(Globals::getImagePath()).append("buttonStop_over.png);}");
	styleString.append("QPushButton:pressed{border-image: url(").append(Globals::getImagePath()).append("buttonStop_down.png);}");
	stopButton->setStyleSheet(styleString);
Aber ich seh gerade, es geht nicht immer mit der Transparenz. Es bleibt im Hintergrund ein schwarzes Rectangle wenn ich die Childwidgets weglasse. Ich setzte es so:

Code: Alles auswählen

QString styleString;	
styleString.append("QWidget{ background: transparent; }");
this->setStyleSheet(styleString);
bassjupp2oo8
Beiträge: 47
Registriert: 17. Juli 2008 09:45

weiterführende Frage

Beitrag von bassjupp2oo8 »

Kann man es auch hinbekommen, dass nur der Hintergrund eines Widgets transparent ist, aber die Schrift (auf zB einem Label) nicht transparent ist?
chris_g
Beiträge: 15
Registriert: 19. November 2009 10:06

Beitrag von chris_g »

Ich habe das wie untenstehend hinbekommen. Allerdings muss es ein TopLevel-Widget sein. Falls man neben das Widget klickt verschwindet es dann, weil es ein eigenes Fenster ist. Als Workaround kann man es mit einem Timer immer wieder nach vorne holen, ist aber nicht wirklich gut gewesen in meinem Fall.

Im Konstruktor eine Widgets:

Code: Alles auswählen

	/* ### Set the Widget to have an translucent background. 
		   It got to be a Top-Level Window to have transparent background.
		   So we must have a timer to move the window to front, or make it modal.
	*/

	setWindowFlags(Qt::FramelessWindowHint);
	setParent(0); // Macht ein ein TopLevel-Widget daraus falls man ein parent übergeben hat...
	setAttribute(Qt::WA_NoSystemBackground, true);
	setAttribute(Qt::WA_TranslucentBackground, true);	

	QTimer *moveToFrontTimer = new QTimer(this);
	QObject::connect(moveToFrontTimer, SIGNAL(timeout()), this, SLOT(moveToFront()) );
	moveToFrontTimer->start(500);
Antworten