Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Giving a QGLWidget a transparent background
Forum Updated to NodeBB v4.3 + New Features

Giving a QGLWidget a transparent background

Scheduled Pinned Locked Moved General and Desktop
27 Posts 5 Posters 19.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    WillWorkForCoffee
    wrote on last edited by
    #1

    Hello!

    If anyone saw my last thread, then you probably already know that I have been piddling around with QGLWidgets in my program.
    I finally got my 3d drawing code to work, only to hit another problem. From what I have tried, I have been unable to successfully give my widget transparency on the form.
    This includes setting the qglClearColor to a color with 0 for the alpha value, and using widget properties to apply the trait. These and other methods I have tried only resulted in a black background.

    Anyone out there have any experience in this? I had seen suggestions that involved using Qpixmaps to make the background "look" transparent, but I needed some other opinions.

    -Kaleb

    1 Reply Last reply
    0
    • W Offline
      W Offline
      WillWorkForCoffee
      wrote on last edited by
      #2

      -bump-
      Surely someone out there has an answer

      1 Reply Last reply
      0
      • W Offline
        W Offline
        WillWorkForCoffee
        wrote on last edited by
        #3

        Really? No one?!

        1 Reply Last reply
        0
        • J Offline
          J Offline
          john_god
          wrote on last edited by
          #4

          This works for me, in the widget constructor:

          @setAttribute(Qt::WA_TranslucentBackground,true);
          setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint );
          setWindowOpacity(0.5);
          bool t=testAttribute ( Qt::WA_TranslucentBackground);
          qDebug()<<"transparency"<<t;@
          
          1 Reply Last reply
          0
          • W Offline
            W Offline
            WillWorkForCoffee
            wrote on last edited by
            #5

            I tried adding that code into the constructor, but unfortunately I can still see the qglclearcolor rather than the transparency. Am I doing something wrong??

            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Which OS are you working on? Either way this is a complex task and can't be done simply by setting some flags etc and has little to do with Qt unfortunately.

              Don't know much about linux so I'll stick to windows.
              On XP there was no window compositing so you're out of luck there. Beginning with Vista desktop compositing is done with DirectX. Windows draw on plain basic DirectX surfaces so you just set up some windows flags and gain direct acces to the window buffer and can efficiently draw to it whatever you want (including alpha channel).

              With OpenGL this is an entirely different story. Windows does not allow so called layered OpenGL contexts(windows). Long story short -there's no simple way, and the hard ones have some drawbacks too (usually performance wise).
              One option is to draw with OpenGL to some offscreen buffer and then copy it to the displayed qpixmap. With some amount of tinkering you can get it pretty efficient, but of course this is still too slow for some serious hi-frame animations. Take a look "here":http://www.dhpoware.com/demos/glLayeredWindows.html

              On the other hand default Qt5 package uses now ANGLE on windows, which is an OpenGL-> DirectX translation layer, so maybe there is a way to get a hand on the native window buffer, but this obviously would be very difficult and hackish to say the least.

              Edit: I played around and it seems that using DwmExtendFrameIntoClientArea with negative margin instead of DwmEnableBlurBehindWindow actually achieves what you want, but again - this requires Windows Vista or higher and platform specific dwmapi.h. I'm also not exactly sure what are the performance penalties with this.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                john_god
                wrote on last edited by
                #7

                The code I paste should work on Vista and above, on linux make sure your window manager has transparency enabled. Please lets us know your OS, Qt version, and small code snippet of what you did, and how are you displaying your widget.

                1 Reply Last reply
                0
                • W Offline
                  W Offline
                  WillWorkForCoffee
                  wrote on last edited by
                  #8

                  john_god:
                  So here is how I have my current form set up. I have a parent form with a few buttons on it, and a QGLWidget is placed on top. I then assign the class "GLWidget" to the QGLWidget. This class is defined in the code and handles drawing the basic cube. Here is where I added your code:
                  @
                  GLWidget::GLWidget(QWidget *parent) :
                  QGLWidget(parent),
                  timer(new QBasicTimer),
                  program(new QGLShaderProgram),
                  geometries(new GeometryEngine),
                  angularSpeed(0)

                  {
                  //setAutoBufferSwap(true);
                  setAttribute(Qt::WA_TranslucentBackground,true);
                  setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint );
                  setWindowOpacity(0.5);
                  bool t=testAttribute ( Qt::WA_TranslucentBackground);
                  qDebug()<<"transparency"<<t;
                  }
                  @

                  As for the platform: I am using Windows 7 Professional edition, and my QT version is Qt5.

                  Krzysztof Kawa: Thanks for your feedback. So what you are essentially stating here is that I could hack together a solution, but it will have performance issues? I took a look at the link you provided, it has some promise if I can find a way to make it somewhat efficient.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    john_god
                    wrote on last edited by
                    #9

                    What happens if you set the transparency to the parent form ?

                    1 Reply Last reply
                    0
                    • W Offline
                      W Offline
                      WillWorkForCoffee
                      wrote on last edited by
                      #10

                      If I place the same code into the parent form's code, it simply does not show up. So clearly the transparency code works for the parent form, but the QGLWidget seems unaltered by it.

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        john_god
                        wrote on last edited by
                        #11

                        Try this on the MainWidget constructor

                            @setAttribute(Qt::WA_TranslucentBackground,true);
                            setWindowOpacity(0.5);
                            bool t=testAttribute ( Qt::WA_TranslucentBackground);
                            qDebug()<<"transparency"<<t;@
                        

                        I just tested in the cube demo and it works great on linux.

                        1 Reply Last reply
                        0
                        • Chris KawaC Offline
                          Chris KawaC Offline
                          Chris Kawa
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Yeah, this works for regular widgets, but doesn't seem to for QGLwidget on Windows.

                          As I said you can try to put this in your constructor as a platform dependent solution:
                          @
                          #include <dwmapi.h>
                          #pragma comment(lib, "dwmapi")

                          //in the constructor
                          setWindowFlags(Qt::FramelessWindowHint);
                          MARGINS m;
                          m.cxLeftWidth = -1;
                          m.cxRightWidth = -1;
                          m.cyBottomHeight = -1;
                          m.cyTopHeight = -1;
                          DwmExtendFrameIntoClientArea((HWND)winId(), &m);
                          @
                          Seems to be working, but check if it meets your requirements.

                          1 Reply Last reply
                          0
                          • W Offline
                            W Offline
                            WillWorkForCoffee
                            wrote on last edited by
                            #13

                            That somewhat accomplished what I wanted, actually!
                            However it gave the entire window transparency, is there a way to only give the background of the QGLWidget transparency?

                            Thanks again!

                            1 Reply Last reply
                            0
                            • Chris KawaC Offline
                              Chris KawaC Offline
                              Chris Kawa
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              The opacity is not the same as full alpha channel transparency. Opacity makes entire window and its contents transparent and doesn't give you per pixel control (eg. only background transparent and the drawings fully opaque).

                              1 Reply Last reply
                              0
                              • W Offline
                                W Offline
                                WillWorkForCoffee
                                wrote on last edited by
                                #15

                                Sorry Krzysztof Kawa, ignore my last post, it was aimed at john_god.
                                I am trying out your code at the moment.

                                1 Reply Last reply
                                0
                                • W Offline
                                  W Offline
                                  WillWorkForCoffee
                                  wrote on last edited by
                                  #16

                                  So, after trying your code Krzysztof Kawa, I did not see a difference.

                                  Here is the constructor of the widget:
                                  @GLWidget::GLWidget(QWidget *parent) :
                                  QGLWidget(parent),
                                  timer(new QBasicTimer),
                                  program(new QGLShaderProgram),
                                  geometries(new GeometryEngine),
                                  angularSpeed(0)

                                  {
                                  setWindowFlags(Qt::FramelessWindowHint);
                                  MARGINS m;
                                  m.cxLeftWidth = -1;
                                  m.cxRightWidth = -1;
                                  m.cyBottomHeight = -1;
                                  m.cyTopHeight = -1;
                                  DwmExtendFrameIntoClientArea((HWND)winId(), &m);
                                  }@

                                  And a screenshot:
                                  This one with no qglclearcolor
                                  !http://img13.imageshack.us/img13/3069/noclear.png(No clear color)!

                                  1 Reply Last reply
                                  0
                                  • J Offline
                                    J Offline
                                    john_god
                                    wrote on last edited by
                                    #17

                                    bq. That somewhat accomplished what I wanted, actually!
                                    However it gave the entire window transparency, is there a way to only give the background of the QGLWidget transparency?
                                    Thanks again!

                                    I don't know. If you find let us know :) I will try other ways.

                                    1 Reply Last reply
                                    0
                                    • Chris KawaC Offline
                                      Chris KawaC Offline
                                      Chris Kawa
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #18

                                      The DWM thingie worked for me. I got this triangle with transparent background:
                                      !http://img801.imageshack.us/img801/7412/transparency.jpg(triangle with transparent background)!

                                      Here's the widget code I used:
                                      @
                                      #include "myglwidget.h"
                                      #include <dwmapi.h>

                                      #pragma comment(lib, "dwmapi")

                                      MyGLWidget::MyGLWidget(QWidget *parent) :
                                      QGLWidget(parent)
                                      {
                                      setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);

                                      MARGINS m;
                                      m.cxLeftWidth = -1;
                                      m.cxRightWidth = -1;
                                      m.cyBottomHeight = -1;
                                      m.cyTopHeight = -1;
                                      DwmExtendFrameIntoClientArea((HWND)winId(), &m);
                                      

                                      }

                                      void MyGLWidget::initializeGL()
                                      {
                                      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                                      }

                                      void MyGLWidget::resizeGL(int w, int h)
                                      {
                                      glViewport(0, 0, w, h);
                                      glMatrixMode(GL_PROJECTION);
                                      glLoadIdentity();
                                      GLfloat x = GLfloat(w) / h;
                                      glFrustum(-x, x, -1.0, 1.0, 1.0, 10.0);
                                      glMatrixMode(GL_MODELVIEW);
                                      glLoadIdentity();
                                      }

                                      void MyGLWidget::paintGL()
                                      {
                                      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                                      glBegin(GL_TRIANGLES);
                                      glColor3f(1.0, 0.0, 0.0);
                                      glVertex3f(-1.0, 1.0, -3.0);
                                      glColor3f(0.0, 1.0, 0.0);
                                      glVertex3f(1.0, 1.0, -3.0);
                                      glColor3f(0.0, 0.0, 1.0);
                                      glVertex3f(0.0, -1.0, -3.0);
                                      glEnd();
                                      

                                      }
                                      @

                                      1 Reply Last reply
                                      0
                                      • W Offline
                                        W Offline
                                        WillWorkForCoffee
                                        wrote on last edited by
                                        #19

                                        Oh man. I placed your code into my GLWidget's code, just to see if it would work. But I am now getting errors that functions like glVertex3f are undefined. Is it a possibility that something with my .lib files is preventing this from working?
                                        Let me give you a lowdown of my environment so you aren't in the dark on this.
                                        I'm running Visual Studio 2010, with the QT 5.0 addin. Here are the additional dependencies in my linker:
                                        @qtmaind.lib
                                        Qt5Cored.lib
                                        Qt5Guid.lib
                                        Qt5Widgetsd.lib
                                        msvcrtd.lib
                                        Qt5OpenGLd.lib
                                        libEGLd.lib
                                        libGLESv2d.lib
                                        gdi32.lib
                                        user32.lib
                                        dwmapi.lib@

                                        The includes I have at the top of the GLWidget:
                                        @#include "GLWidget.h"
                                        #include "geometryengine.h"
                                        #include <QtOpenGL/QGLShaderProgram>
                                        #include <QBasicTimer>
                                        #include <QMouseEvent>
                                        #include <QDebug>
                                        #include <math.h>
                                        #include <locale.h>
                                        #include <dwmapi.h>
                                        #pragma comment(lib, "dwmapi")@

                                        I feel like I'm missing something here. Is there something up with my dependencies or includes?
                                        Thanks again for the help though. I'm confident that your code works flawlessly, my compiler just doesn't like the thought of success lol.

                                        1 Reply Last reply
                                        0
                                        • Chris KawaC Offline
                                          Chris KawaC Offline
                                          Chris Kawa
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #20

                                          Hm, I might be wrong but it looks like yet another type of issue.

                                          The thing is I'm using Qt5 I compiled myself with the -opengl desktop switch, which means I get to use the full desktop OpenGl along with the fixed pipeline (glMatrixMode, glBegin, glVertex etc.).

                                          I'm guessing you are using the default pre-compiled Qt5 package available from download page, which, as I said in one of the earlier post, uses ANGLE - an OpenGL ES implementation on top of DirectX.
                                          I think the fixed pipeline is not available on OpenGL ES. You need to use VBOs, shaders and your own matrix transformations there so the code I pasted is not valid in that scenario. Sorry for the confusion.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved