Important: Please read the Qt Code of Conduct -

From QWidget + QPainter to QOpenGLWidget + QPainter

  • Hi

    I need to do OpenGL rendering on a widget that has a painting routine writen using QPainters
    So i turned my class into a QOpenGLWidget and did the following :

    • Replaced void paintEvent(QPaintEvent* event) override by a void paintGL() override
    • Replaced void resizeEvent(QResizeEvent* event) override by a void resizeGL(int w, int h) override
    • Wrote an empty void initializeGL() override

    Code inside the functions stays the same and there is no OpenGL code in this class

    Yet my widget does not paint like before : it stays black

    So i tried to comment as much code as possible to find what was going on but without success.
    It turned into this

    class Canvas : public QOpenGLWidget
        Canvas(QWidget* parent) : QOpenGLWidget(parent) {
            // code without any OpenGL
        // code without any OpenGL
        void initializeGL() override {}
        void resizeGL(int w, int h) override {}
        void paintGL() override {
            QPainter painter(this);
            painter.fillRect(rect(), Qt::red);
            int a,b,c,d;
            rect().getCoords(&a, &b, &c, &d);
            qDebug() << a << " " << b << " " << c << " " << d;
            // ensure paintGL() is called,
            // ouputs is valid : 0 0 800 600

    And my widget is still black
    Any idea of what is going wrong here ? I read the documentation and other posts scrupulously but i could not find anything relevent

    NB : I am using Qt 5.6

    Thank you for your help in advance

  • Lifetime Qt Champion


    Please take a look at the 2D Painting Example.

  • @SGaist Hi

    I did have a look at this example and I was able to produce a working example myself.
    As i said I have already read many articles + the documentation.
    By the way the linked example does not seem to be so much up to date because the deprecated QGLWidget class is mentionned here and there.
    It should probably makes no difference except that I have tried using QGLWidget instead of QOpenGLWidget and it works
    (same code, only the inherited class differs)

    The thing is I am not writing something "bottom up" here, so I would like to know :

    • If you could confirm my approach of transforming my QWidget into a QOpenGLWidget is good
    • If this approach does not work under certain circumstances and wich ones are concerned
    • What should I look for in my code that could be the cause of my problem (black widget) given the fact that the widget itself does not use any OpenGL code (so the OpenGL states should be ok by the time paintGL is called)

    NB : I have tried to use paintEvent(QPaintEvent* event) instead of paintGL() for the time being because i see this is the way it is done in the example, however it gives the same results.

    I know a lot of messages you get on this forum are due to people not reading the documentation nor the examples but that is not my case, I would really appreciate it if you could give me a consistent answer.


  • For those who end up looking here :
    It seems that this is a Qt 5.6 bug, it works fine in Qt 5.14

    Edit :
    The bug itself may be related to the use of QSurfaceFormat::setDefaultFormat after application startup : Qt 5.14 warned me about a piece of code I was not aware saying that it could cause context sharing issues. Having it removed seems to have solved the bug when i got back to Qt 5.6

Log in to reply