Search code examples
qtqgraphicsviewqglwidget

Widgets with transparent backgrounds over a QGraphicsView with a QGLWidget viewport


I recently tried setting the viewport of my QGraphicsView to a QGLWidget to see how it performs. What I noticed is that widgets which previously had transparent backgrounds (styled buttons, in-game menus that have no background) now have black backgrounds. Is there a simple way to keep the transparency and still use a QGLWidget viewport?

#include <QtCore>
#include <QtWidgets>
#include <QGLWidget>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QMainWindow mainWindow;

    QGraphicsView *view = new QGraphicsView(&mainWindow);

    view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
    view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

    QPushButton *button = new QPushButton(&mainWindow);
    button->setStyleSheet("QPushButton {"
      "border: 2px solid #8f8f91;"
      "border-radius: 6px;"
      "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #f6f7fa, stop: 1 #dadbde);"
      "min-width: 80px;"
      "}");

    QWidget *widget = new QWidget(&mainWindow);
    widget->move(0, 100);

    mainWindow.setCentralWidget(view);
    mainWindow.resize(200, 200);
    mainWindow.show();

    return app.exec();
}

QGLWidget black background example


Solution

  • According to the resolution of the bug report in my comment:

    this is an unavoidable consequence of how QGLWidget works

    It was suggested elsewhere that QGraphicsProxyWidget might solve the problem:

    #include <QtCore>
    #include <QtWidgets>
    #include <QGLWidget>
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QMainWindow mainWindow;
    
        QGraphicsView *view = new QGraphicsView(&mainWindow);
        QGraphicsScene *scene = new QGraphicsScene;
        view->setScene(scene);
    
        view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
        view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    
        QPushButton *button = new QPushButton;
        button->setStyleSheet("QPushButton {"
          "border: 2px solid #8f8f91;"
          "border-radius: 6px;"
          "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #f6f7fa, stop: 1 #dadbde);"
          "min-width: 80px;"
          "}");
    
        scene->addWidget(button);
    
        mainWindow.setCentralWidget(view);
        mainWindow.resize(200, 200);
        mainWindow.show();
    
        return app.exec();
    }
    

    qgraphicsproxywidget-screenshot