Seite 1 von 1
[gelöst] QWidgtet transparent , QT 4.6
Verfasst: 10. Dezember 2009 16:33
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
Verfasst: 11. Dezember 2009 11:22
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:
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]
Verfasst: 13. Dezember 2009 13:23
von AuE
im stylesheet einfach background: transparent; oder?
Verfasst: 14. Dezember 2009 12:47
von chris_g
Das ging bei mir nicht.
Verfasst: 14. Dezember 2009 12:48
von AuE
Sollte es aber

Verfasst: 14. Dezember 2009 13:46
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.
Verfasst: 14. Dezember 2009 14:07
von AuE
Ok.... so gesehen hast natürlich recht.... allerdings kannst zum ausblenden in 100ms auch setVisible auf false setzen
Verfasst: 14. Dezember 2009 14:26
von chris_g
Ne ich blende über in 1 Sekunde aus... Das wären dann 10 mal in einer Sekunde den Stylesheet neu setzen.
Verfasst: 15. Dezember 2009 09:55
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...
Verfasst: 15. Dezember 2009 09:57
von AuE
Wenn du Control anpassen willst wäre in dem Fall allerdings dann border-image die richtige Wahl!
Verfasst: 15. Dezember 2009 10:09
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);
weiterführende Frage
Verfasst: 17. Dezember 2009 14:15
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?
Verfasst: 11. Januar 2010 12:05
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);