PDA

View Full Version : Why does QGraphicsView::update(const QRegion&) cause the whole widget to be updated?



Nick C
14th January 2016, 16:18
I have a large, complicated graphics view that takes a lot of processing to draw, and so I only want to redraw part of it (an OpenGL video display) each frame, leaving the rest (various child widgets etc) unchanged.

However, when I call update() with a QRegion, the paintEvent's region is the full size of the widget, so the whole screen gets redrawn every time. There doesn't appear to be any call to update() with no parameters (at least, not my version thereof)

What might be causing the paint event to have the full screen in it?



void GLGraphicsView::updateVideoRegion(const QRegion & r)
{
//this function called from outside...
LOG4CXX_DEBUG(_logger, "updateVideoRegion " << r.boundingRect().x() << " " << r.boundingRect().y() << " " << r.boundingRect().width() << " " << r.boundingRect().height());
update(r);
}

void GLGraphicsView::update()
{
LOG4CXX_DEBUG(_logger, "update(all)");
QGraphicsView::update();
}

void GLGraphicsView::update(const QRegion& region)
{
LOG4CXX_DEBUG(_logger, "update(region) " << region.boundingRect().x() << " " << region.boundingRect().y() << " " << region.boundingRect().width() << " " << region.boundingRect().height());
QGraphicsView::update(region);
}

void GLGraphicsView::paintEvent(QPaintEvent *e)
{
LOG4CXX_DEBUG(_logger, "repaint region " << e->region().boundingRect().x() << " " << e->region().boundingRect().y() << " " << e->region().boundingRect().width() << " " << e->region().boundingRect().height());

/* Do the rest of the painting */
}

Output:


updateVideoRegion 19 19 1446 568
update(region) 19 19 1446 568
repaint region 0 0 1920 1201


I've also tried using updateScene(QList<QRectF>) instead of update(QRegion), but that doesn't seem to cause a paintEvent to be generated?

Can I make it only re-draw the region that has changed? If not, why not?

yeye_olive
14th January 2016, 16:42
What are the view's viewportUpdateMode and cacheMode?

Nick C
15th January 2016, 10:44
Both are set to none (CacheNone and NoViewportUpdate respectively). Setting cache to CacheBackground stops the OpenGL stuff rendering, and changing the viewport update settings doesn't seem to make any difference - the region passed into the paintEvent is always the full screen

Nick C
15th January 2016, 14:13
After further investigation, it appears that this is because I am using OpenGL - the 'fullUpdate' flag in updateScene is always set in this case - qgraphicsView has "accelerateScrolling = !isGlWidget" [in setupViewport, line 2759] and "fullUpdate = !d->accelerateScrolling" [in updateScene, line 2675]