Search code examples
qtqgraphicsviewqgraphicssceneqtopengl

Embedding a QOpenGLWidget via addWidget in QGraphicsScene


Some time ago I created a subclass of QGraphicsView that I called MultiWidget. Its purpose was to hold some other widgets I use, which I added with addWidget to the QGraphicsScene associated to my MultiWidget.

The idea was, that MultiWidget should present a "notebook like" view of all these added widgets, displaying them from top to bottom, one under the other and give (as an extra gimmick) a little green knob, with which the widget could be toggled between hidden and displayed:

enter image description here

Now I tried to add a new widget GPURenderWidget, derived from QOpenGLWidget with addWidget method of MultiWidget, which worked first seemingly without error. But: The content of the GPURenderWidget which is displayed through paintGL does not get displayed properly on the pane of the MultiWidget: An initial picture is shown, but albeit new frames are generated in a sequence of paintGL calls in GPURenderWidget, the view in MultiWidget does not get updated (the following is the still view that is presented):

enter image description here

I already set the viewport of my MultiWidget to OpenGL-form via

 setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));

Am I forced to abandon this approach? And what would be the best alternative? Should I create a GPURenderItem derived from QGraphicsItem and add that to QGraphicsView via addItem() ? But I would prefer to let GPURenderWidget remain a QOpenGLWidget so that it can be used as a standalone widget on other places. Or must I sacrifice the whole MultiWidget-approach with addWidget to a QGraphicsScene?


Solution

  • The documentation for QGraphicsProxyWidget has a couple of notes/warnings, specifically...

    Warning: This class is provided for convenience when bridging QWidgets and QGraphicsItems, it should not be used for high-performance scenarios. In particular, embedding widgets into a scene that is then displayed through a QGraphicsView that uses an OpenGL viewport will not work for all combinations.

    and...

    Note that widgets with the Qt::WA_PaintOnScreen widget attribute set and widgets that wrap an external application or controller cannot be embedded. Examples are QOpenGLWidget and QAxWidget.

    So I think you're out of luck with regard embedding a QOpenGLWidget directly in a QGraphicsScene.

    One possible alternative would be to use an framebuffer object for the OpenGL rendering and grab/blit the generated frames from the FBO to a simpler custom widget that can be embedded.