5

I need to draw transparent window (either QLabel or QFrame or QWidget), but without using WA_TranslucentBackground. The reason for that is that the windows will contain other child widgets rendered through OpenGL, and using that property makes those windows invisible on Windows, as documented here. This works fine in Mac though, I need a different solution on Windows only, as it does not work there. I tried this: setting a blank pixmap. But it still shows up with a grey background:

#include <QApplication>
#include <QLabel>
#include <QBitmap>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QLabel l;
    l.setWindowFlags(Qt::FramelessWindowHint);
    QPixmap p("");
    l.setPixmap(p);
    l.setScaledContents(true);
    l.resize(300, 500); //just to test my idea
    l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
    Qt::SmoothTransformation).mask());
    l.show();
    return a.exec();
}

Can anyone suggest any other means of achieving this on Windows, i.e a fully transparent window? Platform - Qt 5.3.1, 32 bit.

P.S - It need not behave like translucent window, i.e where the background can be clicked through the transparent parts of a widget rendered though WA_TranslucentBackground. Here as long as it is transparent it will be okay, it need not be clickable 'through'.

SexyBeast
  • 7,913
  • 28
  • 108
  • 196
  • Maybe use SetWindowRgn so the parent window region will consist of the child window rectangles thus creating the illusion of an invisible parent. – Jonathan Jan 13 '16 at 12:37
  • Can you add a minimal working example as an answer? – SexyBeast Jan 13 '16 at 12:49
  • I'm currently not near a proper compilation environment. But here is a link to a codeproject page which uses SetWindowRgn to create holes in a window. http://www.codeproject.com/Articles/291/Creating-holes-in-a-window – Jonathan Jan 14 '16 at 10:06

3 Answers3

3

I am on Windows (Qt 5) and use the following to create a Semi-Transparent Widget:

setWindowOpacity(0.6);
setStyleSheet("QWidget{background: #000000}")

It should work if you set the opacity to zero. I use this together with the Windows flags "framelessWindow" and "Tool" to darken the background of the screen.

Mailerdaimon
  • 6,003
  • 3
  • 35
  • 46
  • If I set the opacity to zero, won't all child widgets become invisible as well? – SexyBeast Jan 11 '16 at 06:54
  • Sorry, I don't know as I don't have any child Widgets in my Setup and it is not explicitly stated in the documentation. – Mailerdaimon Jan 11 '16 at 07:27
  • This still doesn't work. The background is grey as before. – SexyBeast Jan 11 '16 at 12:00
  • I have just tried a minimal example and setting the WindowOpaciy does work for me, however, as you mentioned in your comment, all the child widgets become translucent. If you do not get any kind of transparency maybe something was broken in 5.3? Tranparency + OpenGL (or QML) was never an easy topic in Qt. – Mailerdaimon Jan 11 '16 at 12:29
  • Not it works. Sorry. However, it won't be a viable solution in my case as child widgets would become invisible as well. – SexyBeast Jan 11 '16 at 12:31
  • Is there a way you could make your widgets siblings instead of childs? This way positioning might be a hassle but at least the transparency should work, – Mailerdaimon Jan 11 '16 at 12:34
  • Nah. Already considered and discarded. For every widget that now comes in we will have to handle positioning. That wouldn't be a problem, but the widget needs to be movable as well, which in absence of title bar, we are implementing manually, and that causes a very visible 'gap' between the child widgets and the parent, we see the child widgets 'chasing' the parent as the parent is dragged along.. – SexyBeast Jan 11 '16 at 12:36
2

transparency can be achieved by enabling blur behind window and by setting windows attribute to WA_TranslucentBackground

  setAttribute(Qt::WA_TranslucentBackground);
    QtWin::enableBlurBehindWindow(this); 

required , cpp include : include<QtWin>, project file include : QT += winextras

enter image description here

the method enableBlurBehindWindow() has two more overload ,you can look those on this documentation

For child widgets you can use

setStyleSheet("background:transparent");
Ramesh Choudhary
  • 366
  • 4
  • 11
1

Unfortunately this is not possible on Windows. You can set transparency for widget with color with alpha-channel like this: setStyleSheet("background-color: rgba(255,0,0,50%);");. But whis is doesn't work for top level widget until you set WA_TranslucentBackground. Without this flag alpha-channel doesn't work and you get black window. So the only solution is use WA_TranslucentBackground. And then do OpenGL painting like Qt documentation says:

To work around this issue you can either just use Qt to render everything and not OpenGL, or you can render the OpenGL into a pixmap and draw that onto your widget instead.

Evgeny
  • 3,910
  • 2
  • 20
  • 37