August 18, 2013

kenchan kenchan
Ant Farmer
126 posts

[Solved]-How can I make a QDockWidget transparent when floating?

 

Hello,

To continue my QDockWidget series… I would like to make a QDockWidget transparent when it is floating, meaning I want to see through it.

I have looked around and found several threads that discuss making widgets transparent but I can’t seem to get anything to work with a QDockWidget. When there are several widgets involved in a dock widgets which one do I make transparent the top most parent? or each child?

The code below is a Main Window application with a menu bar, tool bar, status bar and a central widget. I have added a QDockWidget and some code to make it transparent. The title bar of the dock widget is transparent (50%) when docked but the background is not transparent when docked or floated. It would nice if it was :-).

Can anyone tell me if there is a way to do this on both Windows and Mac?
I would appreciate any help at all.

Thanks

  1. #include <QApplication>
  2. #include <QMainWindow>
  3. #include <QAction>
  4. #include <QMenuBar>
  5. #include <QToolBar>
  6. #include <QMenu>
  7. #include <QTextEdit>
  8. #include <QStatusBar>
  9. #include <QGridLayout>
  10. #include <QDockWidget>
  11. #include <QToolButton>
  12. #include <QPalette>
  13. #include <QString>
  14. #include <QFont>
  15. #include <QDebug>
  16.  
  17. QString appeal = "Hello everyone,\n\nPlease help me make my dock widget have a transparent background when it is floated.\n\nThank you.";
  18.  
  19. int main(int argc, char *argv[])
  20. {
  21.     QApplication a(argc, argv);
  22.     QMainWindow *w = new QMainWindow();
  23.     w->resize(800,600);
  24.  
  25.     // add a status bar
  26.     QStatusBar *statusBar = new QStatusBar(w);
  27.     w->setStatusBar(statusBar);
  28.     statusBar->showMessage("Please Make my Dock Widget See Thru :-)");
  29.  
  30.     // add an exit menu
  31.     QMenu *fileMenu = new QMenu();
  32.     QAction *exitAct = new QAction("E&xit", w);
  33.     exitAct->setShortcuts(QKeySequence::Quit);
  34.     exitAct->setStatusTip("Exit the application");
  35.     exitAct->setShortcut(QKeySequence("Ctrl+Q"));
  36.     w->connect(exitAct, SIGNAL(triggered()), &a, SLOT(closeAllWindows()));
  37.     fileMenu = w->menuBar()->addMenu("&File");
  38.     fileMenu->addAction(exitAct);
  39.  
  40.     // add a tool bar
  41.     QToolBar *toolBar = new QToolBar("A Toobar",w);
  42.     toolBar->setAllowedAreas(Qt::AllToolBarAreas);
  43.     toolBar->addAction(exitAct);
  44.     w->addToolBar(Qt::TopToolBarArea,toolBar);
  45.  
  46.     // add a central widget
  47.     QTextEdit *central = new QTextEdit(w);
  48.     QFont font;
  49.     font.setFamily("Helvetica");
  50.     font.setPointSize(24);
  51.     font.setBold(true);
  52.     central->setFont(font);
  53.     central->setText(appeal);
  54.     w->setCentralWidget(central);
  55.  
  56.     // add the dock widget
  57.     QPalette pal;
  58.     QDockWidget *seeThruDock = new QDockWidget("See Thru",w);
  59.     seeThruDock->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
  60.  
  61.     // HOW TO SET TRANSPARENCY WHEN FLOATING???
  62.     seeThruDock->setWindowFlags(seeThruDock->windowFlags()|Qt::FramelessWindowHint);
  63.     seeThruDock->setAttribute(Qt::WA_TranslucentBackground ,true);
  64.     seeThruDock->setAutoFillBackground(false);
  65.     pal = seeThruDock->palette();
  66.     pal.setBrush(QPalette::Window, QColor(255, 0, 0, 128) );
  67.     seeThruDock->setPalette(pal);
  68.  
  69.     // add a contents widget
  70.     QWidget *seeThruContents = new QWidget();
  71.     seeThruContents->setMinimumSize(QSize(72,40));
  72.  
  73.     // add a widget for a layout
  74.     QWidget *gridLayoutWidget = new QWidget(seeThruContents);
  75.     gridLayoutWidget->setGeometry(QRect(0,0,72,40));
  76.  
  77.     // add a grid layout
  78.     QGridLayout *gridLayout = new QGridLayout(gridLayoutWidget);
  79.     gridLayout->setSpacing(2);
  80.     gridLayout->setContentsMargins(2,2,2,2);
  81.  
  82.     // add couple of tool bar buttons to the layout
  83.     QToolButton *Tb_1 = new QToolButton(gridLayoutWidget);
  84.     Tb_1->setIconSize(QSize(32,32));
  85.     gridLayout->addWidget(Tb_1,0,0,1,1);
  86.     //
  87.     QToolButton *Tb_2 = new QToolButton(gridLayoutWidget);
  88.     Tb_2->setIconSize(QSize(32,32));
  89.     gridLayout->addWidget(Tb_2,0,1,1,1);
  90.  
  91.     // set the dock widget
  92.     seeThruDock->setWidget(seeThruContents);
  93.     seeThruDock->setAllowedAreas(Qt::AllDockWidgetAreas);
  94.     w->addDockWidget(Qt::LeftDockWidgetArea,seeThruDock);
  95.  
  96.     w->show();
  97.     return a.exec();
  98. }

13 replies

August 20, 2013

Santosh Reddy Santosh Reddy
Lab Rat
81 posts

How do you plan to float the dock widget?

If you plan to float the dock widget using mouse, then the momment you drag the title bar of the dock widget it will pop out and immdiately the FramelessWindowHint (should be explicitly set) will be set and you will lose track of the dock widget’s titlebar… think of this!

If you only want to float it programatically, then connect a slot to topLevelChanged() of dock widget and set the window flags in there.

Note the trick is to set the WA_TranslucentBackground flag every time after floating the dock widget not before.

 Signature 

SS

August 20, 2013

raven-worx raven-worx
Dinosaur Breeder
1628 posts

connect to QDockWidget::topLevelChanged() signal and use QWidget::setWindowOpacity() [qt-project.org] to set it semi-transparent.

August 20, 2013

kenchan kenchan
Ant Farmer
126 posts

I see, Thank you both for your suggestions. Good point about the loosing track of the title bar. I give your suggestion a try and see how it goes.

August 22, 2013

kenchan kenchan
Ant Farmer
126 posts

Hello raven-worx,

I tried your suggestion and it works fine for the dock widget. The problems is that any child widgets (tool buttons in my case) are also the same level of transparency.

I don’t want my buttons to be transparent. Setting their opacity to 1.0 did not have any effect.

Is there any way to keep the buttons (children) opaque?

Many thanks.

August 22, 2013

raven-worx raven-worx
Dinosaur Breeder
1628 posts

AFAIK this isn’t possible.

August 22, 2013

kenchan kenchan
Ant Farmer
126 posts

Ah, I see. Well it’s close to what I am looking for. I will try some more approaches and see how it goes.

Thanks to all for the help.

August 22, 2013

kenchan kenchan
Ant Farmer
126 posts

Hello again, we seem to have just lost some posts when the server went down.

Santosh, I tried your suggestion to use setAutoFillBackground(true) on the child widgets. I set it on the buttons but it did not have any effect.

Thanks for the suggestion though.

August 22, 2013

Santosh Reddy Santosh Reddy
Lab Rat
81 posts

QToolButtons and QPushButtons will not be transparent, there is somthing you are missing, can you show the screenshot of the problem?

 Signature 

SS

August 22, 2013

kenchan kenchan
Ant Farmer
126 posts

OK, here is a screen shot of the transparent dock widget floating over the background.

https://www.dropbox.com/s/784h7cgmyltiotm/TransparentDockWidget.png

As you can see the buttons are also transparent.

August 24, 2013

kenchan kenchan
Ant Farmer
126 posts

Hello again,

I have found that if you use the setWindowOpacity() function on the parent the children are all transparent also
if you use the following:

  1. setWindowFlags(Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground);
  2. setStyleSheet("background:rgba(0,0,0,50%);");

on the top level widget naturally you get a frameless transparent window but you can change the transparency of children which are not direct descendants of the frameless window. You can control the transparency and color of the children using a style like this for example:
  1. setStyleSheet("MyToolButton { color: black; background: white; border-radius: 5px; }");

using setWindowOpacity() on the children does not work.
You can probably do this with a palette but I have not tried that.

The kicker is… I can’t get this to work when the top level widget is a QDockWidget. I can only make the QDockWidget transparent using setWindowOpacity().

I am sure all those experience with using transparency know all this. Are my findings correct or is there more that I am missing?

Thanks.
PS. I will post some code to show this later.

August 24, 2013

kenchan kenchan
Ant Farmer
126 posts

Unfortunately this discussion did not help me put opaque buttons on a QDockWidget but it pointed me in another direction and I learned something about transparency. I guess Dock Widgets are complex things but I will keep trying. I have marked this thread solved because it did result in me getting a transparent doc widget. Maybe I should start a new thread to ask about making the buttons transparent.

For those who might find this useful here is some code to go with my previous post. You can tweak the style sheet stuff and change the colour and transparency of the children.

Thanks again Santosh and raven-worx for your help . If you have any other ideas please post again.

  1. int main(int argc, char *argv[])
  2. {
  3.     QApplication a(argc,argv);
  4.  
  5.     // a transparent top level widget
  6.     QWidget *widget = new QWidget;
  7.     widget->setWindowFlags(Qt::FramelessWindowHint);
  8.     widget->setAttribute(Qt::WA_TranslucentBackground);
  9.     widget->setStyleSheet("background:rgba(0,0,0,50%);");
  10.     widget->setFixedSize(QSize(500,500));
  11.  
  12.     // a label so we can see the top widget
  13.     QLabel *label = new QLabel(widget);
  14.     label->setFixedSize(500, 500);
  15.     label->setStyleSheet("border-radius: 20px;");
  16.  
  17.     // a close button
  18.     QPushButton *button = new QPushButton(label);
  19.     button->setGeometry(20,20,100,50);
  20.     button->setStyleSheet("background-color: white; border-radius: 10px;");
  21.     button->setText("Close");
  22.     widget->connect(button, SIGNAL(pressed()), &a, SLOT(closeAllWindows()));
  23.     button->setShortcut(QKeySequence("Ctrl+Q"));
  24.     button->setToolTip(a.tr("Close the application (Qtrl-Q)"));
  25.  
  26.     // a widget for some other content also transparent
  27.     QWidget *contentWidget = new QWidget(label);
  28.     contentWidget->setGeometry(25,150,450,200);
  29.  
  30.     // an opaque label for the content
  31.     // if you don't use the style it will also be transparent
  32.     QLabel *label2 = new QLabel(contentWidget);
  33.     label2->move(20,20);
  34.     label2->setText("This is a QWidget");
  35.     label2->setStyleSheet("color : black; background-color : white; border-radius: 0;");
  36.  
  37.     widget->show();
  38.  
  39.     return a.exec();
  40. }

October 20, 2013

amonR amonR
Lab Rat
50 posts

Kenchan you just saved my life!!! Thanks a lot for your post!!!

October 21, 2013

kenchan kenchan
Ant Farmer
126 posts

Hello amonR,

I am glad to hear something in this post was useful to someone :-).

Since Qt5.1 this also works quite well on Mac OSX.

 
  ‹‹ How can I use glGenSamplers in OpenGL version 3.2 ?      Need help on proper way to deploy to Windows ››

You must log in to post a reply. Not a member yet? Register here!