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



  • 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
    

    <edit>
    I've also tried using updateScene(QList<QRectF>) instead of update(QRegion), with viewportUpdateMode set to SmartViewportUpdate, but the paintEvent's region is still the full size of the screen

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



  • 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]



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.