0
votes

I wanted to use openGL to render QGraphicsview items so that I can save CPU power. In the documentation it states that what I have to do is add a QOpenGLWidget as the view port of the QGraphicsview. This is what I'm doing:

QOpenGLWidget *glWidget = new QOpenGLWidget();
ui->drawScreen->setViewport(glWidget);
ui->drawScreen->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
ui->drawScreen->update();

(ui->drawScreen is my QgraphicsView)

When I draw something on the screen it draws correctly but after a certain time I want to remove the item with a fade animation. That isn't provoking the screen to update, i.e., when I do this:

double opacity = 1.0 - ((elapsed - annotationFrameOut) / (double)fadeOutFrames);
(*i)->setOpacity(opacity);

(*i) is one item.

Or this:

scene.removeItem(item);

Visually, nothing happens. Only when I re-size the screen does the item disappear, or show the correct opacity in case it's fading.

Also, when I move an item no position disappears so it creates a dragging effect. Same for the selection rectangle or when typing in a text item (the bounding rect is drawn multiple times).

This seems like a simple update problem but I can't figure out what to do, nor do I seem to find this issue online. I am using Windows.

Thank you for your time.

EDIT: Picture exemplifying the problem. Blue rectangles are the selection rectangles that are never removed (unless I re-size the window) Blue rectangles are the selection rectangle that is never removed (unless I re-size the window)

EDIT 2: Code using QGLWidget

QGLWidget *viewPort = new QGLWidget(QGLFormat(QGL::SampleBuffers | QGL::AlphaChannel), ui->drawScreen);

ui->drawScreen->setViewport(viewPort);
ui->drawScreen->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
ui->drawScreen->update();

EDIT 3: In my app I have a video playing bellow the QGraphicsView. I show the video by updating a QLabel every time a new frame comes up.

Instead of using a QLabel I tried to update the QPixmap of a QGraphicsPixmapImage. If now I draw on top of this image the drawing is being correctly refreshed, I guess because the picture is being updated constantly. But outside of the picture it still doesn't work.

3
It looks like you're not updating your window. Have you tried calling the function 'update()'? It's a function that's part of QOpenGLWidget inherited from QWidget. Call the function in your paintGL() or wherever you update the main loop of your program.Poriferous
I have extended the QGraphicsView class. Inside of it, I have a method that checks when the drawn items should be erased (based on frames from a video). In there I have tried to do viewport()->update() or call the view's update() but it isn't working. Without openGL this works well (even without that call). Do I have to extend the QOpenGLWidget and implement my own paintGL? It seems that not only my operations, but anything that means removing a drawn item does not update (e.g. selection rectangle).Solidus
I have added a picture to help illustrate this.Solidus
Call QOpenGLWidget's update() function. In all honesty you should draw up a class diagram and decide whether you want to inherit from QOPenGLWidget or not. For what it's worth, you are mixing two rendering APIs together. At this point, you'd have to ask yourself whether it's worth going down the low-level lane of OpenGL (not a bad thing at all) is worth it or not. For just to shed some CPU power, I say go with Graphics View and not try to get the GPU to render it.Poriferous
@Poriferous The advice to manually call update() is wrong. The whole point of using QGraphicsView is that such things are handled automatically. Your comment about "mixing" two rendering APIs is wrong too - Qt fully supports using QPainter on an OpenGL context. This is supposed to work, and indeed it did work with the old QGLWidget.Kuba hasn't forgotten Monica

3 Answers

1
votes

The explicit update() call is unnecessary. This looks like a Qt bug. The QGraphicsView does some magic to a QGLWidget to make it work as a viewport. Most likely, this magic hasn't been ported to work with QOpenGLWidget.

As a workaround, use QGLWidget instead.

1
votes

It seems the problem lies with the stylesheet I used to change the background color of the view. Adding a stylesheet to the widget also produces the same bug. With a stylesheet the view-port just becomes black and the refresh of items doesn't seem to work properly.

I removed the stylesheet and changed the background-color by re-implementing the drawBackground function.

Thanks to Kuba Ober for helping me figure out this.

0
votes

In some way the stylesheet generate a repaint bug, even in my case I have removed the stylesheet and everything works correctly.