QOpenGLWidget和透明度

时间:2015-08-29 12:59:49

标签: qt opengl transparency

QOpenGLWidget及其背景颜色存在小问题。

当我想使用QOpenGLWidget在我的自定义QPainter上创建半透明矩形时,会有两种不同的结果:

  1. 如果MyCustomWidget有父级 - 在每次更新时,矩形的颜色会倍增(并且在几次重绘之后它是不透明的,就像以前的绘画结果未清除一样)
  2. 如果MyCustomWidget没有父母 - 每次都不重新粉饰
  3. 以下是QPainter的代码示例:

    class Widget : public QOpenGLWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0)
            : QOpenGLWidget(parent)
        {
            resize(800, 600);
    
            Test *test = new Test(this);
        }
    
        ~Widget(){}
    protected:
        void paintEvent(QPaintEvent *) {}
    
    protected:
        void initializeGL() {
            if(paintEngine()->type() != QPaintEngine::OpenGL &&
                paintEngine()->type() != QPaintEngine::OpenGL2)
                qDebug() << "ERROR. Type is: " << paintEngine()->type();
        }
    
        void resizeGL(int, int) {}
    
        void paintGL() {
            QPainter p;
    
            p.begin(this);
            {
                p.fillRect(rect(), Qt::white);
            }
            p.end();
        }
    
    private:
        class Test : public QOpenGLWidget
        {
        public:
            Test(QWidget *parent = 0) : QOpenGLWidget(parent) {
                resize(100, 100);
            }
    
        protected:
            void paintEvent(QPaintEvent *) {
                QPainter p(this);
                p.fillRect(rect(), QColor(125, 125, 125, 255/10));
            }
        };
    };
    

    默认情况下,它还有黑色背景(我不知道如何修复它。setAttribute(Qt::WA_TranslucentBackground)没有帮助。)

    此外,当我尝试使用glClear清除颜色时,它会忽略alpha(QOpenGLWidget与父级一起而不是)。这是前面代码中的Test类,但现在它使用opengl来清除颜色:

        class Test : public QOpenGLWidget
        {
        public:
            Test(QWidget *parent = 0) : QOpenGLWidget(parent) {
                resize(100, 100);
            }
    
            void initializeGL() {
                QOpenGLFunctions *f = context()->functions();
    
                f->glClearColor(0.0f, 1.0f, 0.0f, 0.1f);
            }
    
            void paintGL() {
                QOpenGLFunctions *f = context()->functions();
    
                f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            }
        };
    

    我该如何解决这个问题?

    我使用的是Qt 5.5.0,Windows 10,MinGW 4.9.2

3 个答案:

答案 0 :(得分:0)

据我所知,QOpenGLWidget总是先绘制。因此,您无法显示下面分层的任何小部件。我目前正在研究同样的问题。当我找到任何解决方案时,我会回报。

答案 1 :(得分:0)

我遇到类似的问题QOpenGLWidget未在透明区域正确重新绘制,并决定切换到QOpenGLWindow包裹在QWidget::createWindowContainer()

答案 2 :(得分:0)

Xeed 说 QOpenGLWidget 首先被绘制是正确的。

我不是专家,但我想我找到了解决方案。您需要设置一个小部件属性以始终使小部件堆叠在顶部(将小部件视为窗口上的图层)。 Here 是我获得以下信息的链接:

<块引用>

附言正如 QQuickWidget 帖子中提到的,当使用 QQuickWidget 或 QOpenGLWidget 作为子部件时,半透明有一个限制。对于绝对需要此功能的应用程序,Qt 5.4 提供了一种解决方法:新引入的 Qt::WA_AlwaysStackOnTop 小部件属性。这以破坏其他类型布局的堆叠顺序为代价,使得半透明的 QQuickWidget 或 QOpenGLWidget 与其他可见的小部件成为可能。当然,如果只是为了让桌面上的其他应用在下方可见,那么Qt::WA_TranslucentBackground属性就足够了

Python 中的解决方案:

设置 OpenGL 小部件的属性 setAttribute(Qt.WA_AlwaysStackOnTop)

现在 OpenGL 小部件被视为窗口中的“顶部”。使用 'glClearColor' 函数并将 alpha 通道指定为零 (0.0)。

glClearColor(0.0, 0.0, 0.0, 0.0)

我不确定如何用其他语言编写它,但这对我有用。 OpenGL 小部件不再具有默认的黑色背景。它是透明的!希望这会有所帮助。