QOpenGLWidget and QGraphicsDropShadowEffect



  • Hi everyone.
    I need some information. I want to make a parent widget have drop down shadow with QGraphicsDropShadowEffect. It is working correct, but when I try to add a QOpenGLWidget child to that parent it all goes to hell :) :) According to the documentation you can't make the QOpenGLWidget transparent and to expect it to work because it is drawn first. But it also valid for the parent? I don't want to make the GLwidget transparent but it's parent. Is this even possible, even with different method then QGraphicsDropShadowEffect? Again I don't need the GL Widget to be semi-transparent, I need the parent widget.

    Xumepoc.


  • Lifetime Qt Champion

    Hi,

    One of the thing that will interfere is that a QGraphicsEffect set on a widget will also affect all its children and OpenGL base widgets are not supported by QGraphicsEffect.



  • SGaist as always thanks for the fast replay!

    So is there any way to have a window casting shadows and also including a QOpenGLWidget? If I just don't set the OpenGLWidget as child to the window, would it be possible for that widget to be display above the window or because it is always drawn first it will fo behind?

    Xumepoc


  • Lifetime Qt Champion

    So it would layered like:

    • OpenGL Widget
    • Standard Widget

    ?



  • What I want to do is to make a window which is casting shadow. I have already done that for all of the rest of the windows in the application, but the problem is the one which have QOpenGLWidget. And I am losing the consistency. So is there a way to always show the QOpenGLWidget on top of that window (moving and resizing is no problem) without being a child to that window. Because the window is basicly a transparent widget and has one child widget with QGraphicsDropShadowEffect casting the shadow.

    Xumepoc


  • Lifetime Qt Champion

    So basically create that QOpenGLWidget in your "shadowed" window and manage its size from the resize event of the "parent" widget ?



  • The problem there is that when you click on the "shadow" window, the QOpenGLWidget goes behinds, as it is now a child of that window.....


  • Lifetime Qt Champion

    Can you show how you are setting the shadow and OpenGL widget ?



  • Sure thing, this is a pseudo code missing the things which shouldn't matter for the problem.

    class TestWidget : public QWidget
    {
        Q_OBJECT
    public:
    
        TestWidget(SharedStaticDataSet* PSSDS = 0, XWindowManager* manager = 0, QWidget * parent = 0);
    virtual ~TestWidget();
    protected:
        void resizeEvent(QResizeEvent *event);
    
    private:
        GLWidget* glWidget;
    };
    TestWidget::TestWidget(QWidget * parent): QWidget(parent)
    {
        setStyleSheet("background-color: rgb(90,90,90);");
    
        QGraphicsDropShadowEffect* bodyShadow = new QGraphicsDropShadowEffect();
        bodyShadow->setBlurRadius(10);
        bodyShadow->setColor(QColor(0, 0, 0, 200));
        bodyShadow->setOffset(0.0);
        setGraphicsEffect(bodyShadow);
    
        glWidget = new GLWidget();
        glWidget ->setWindowFlags (Qt::ToolTip | Qt :: FramelessWindowHint);
        glWidgrt->show();
    }
    estWidget::~TestWidget()
    {
       delete glWidget;
    }
    void TestWidget::resizeEvent(QResizeEvent *event)
    {
       QPoint newPos = this->mapToGlobal(this->pos());
       glWidget->move(newPos);
       glWidget->resize(event->size()); 
    }
    class ParenWidget: public QWidget
    {
        Q_OBJECT
    public:
        ParenWidget(QWidget * parent = 0);
    
    protected:
        void resizeEvent(QResizeEvent *event);
    
    private:
        TestWidget * testWidget;
    };
    
    ParenWidget::ParenWidget(QWidget * parent): QWidget(parent)
    {
      testWidget = new TestWidget(this);
    
      setWindowFlags (Qt::ToolTip | Qt :: FramelessWindowHint);
      setAttribute(Qt::WA_TranslucentBackground);
    }
    void ParenWidget::resizeEvent(QResizeEvent *event)
    {
        testWidget->move(20,20);
        testWidget->resize(width() - 20, height()  - 20);
    }
    
    class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    public:
        GLWidget ( QWidget* parent = 0);
    protected:
        void initializeGL();
        void paintGL();
        void resizeGL(int w, int h);
    };
    
    GLWidget::GLWidget ( QWidget* parent) : QOpenGLWidget(parent)
    {
    ...
    }
    void  GLWidget::initializeGL()
    {
        initializeOpenGLFunctions();
    ...
    }
        void  GLWidget::paintGL()
    {
    ...
    }
        void  GLWidget::resizeGL(int w, int h)
    {
    ...
         QOpenGLWidget::resize(w, h);
    }
    
    

  • Lifetime Qt Champion

    So if I understand this correctly you have a translucent widget that contains a widget with a shadow effect that itself contains a QOpenGLWidget.

    So In Z order:

    • QOpenGLWidget
    • QWidget with shadow
    • Translucent QWidget

    Right ?



  • Correct. So how to keep the Z order constant?


  • Lifetime Qt Champion

    Since you have some special stuff in there. Can you create a minimal sample that shows that behavior ?



  • Lol I totally missed this. I will try to do it soon.



  • Well after couple of weeks fighting with this I gave up and switched to the setMask() version of the window. All OS now have drop effects anyway (well above Windows 7 on Microsoft site at least). And the rounded edges are not as smooth as in the previous version, but at least it works without any bugs.

    The problem I had so far was, that there is no way to force the OS to put the windows/widgets in the order you want at the time of onfocusIn/out events. The effect is that the openGL widget flickers when you click on it and if you have a menubar and menu, sometimes it is hidden behind the openGL widget. Also on every 5-6 time, the openGL widget just stays behind the main widget and you have to click again on it in order to be bring back on top.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.