QGraphicsScene taking long to update



  • I am trying to get a QGraphicsScene to update at a fixed rate with a timer.

    An example of what I'm trying to achieve is to animate a rectangle moving across the screen with its x position being incremented every frame (for example at 120 fps). However, when calling update() on the QGraphicsScene, it takes about 16 msec to complete (even when the scene is empty, as in the example below). This caps the frame rate at about 60, and the slowdown accumulates if there is more than one QGraphicsScene that needs to get updated.
    What is the right way to go about this?
    Thanks!

    import qt
    
    class View(qt.QGraphicsView):
        def __init__(self):
            qt.QGraphicsView.__init__(self)
            self.setScene(qt.QGraphicsScene())
            
    class Window(qt.QDialog):
        def __init__(self):
            qt.QDialog.__init__(self)
            self.setLayout(qt.QVBoxLayout())
    
            self.view = View()
            self.view.setViewportUpdateMode(qt.QGraphicsView.NoViewportUpdate)
            self.layout().addWidget(self.view)
    
            self.btn = qt.QPushButton('Start')
            self.btn.clicked.connect(self.clicked)
            self.layout().addWidget(self.btn)
    
            self.time = qt.QTime()
    
            self.timer = qt.QTimer()
            self.timer.timeout.connect(self.runUpdate)
    
            self.frame = 0
            self.dontUpdate = False
    
        def clicked(self):
            self.timer.start(1)
    
        def runUpdate(self):
            self.frame += 1
            self.time.start()
            if not self.dontUpdate:
                self.view.scene().update()
            print(self.time.elapsed(), qt.QTime.currentTime().msec(), self.frame)
    
    app = qt.QApplication([])
    window = Window()
    window.show()
    app.exec_()
    

    Note: the script above is using the following python module (qt.py),

    from PySide2.QtCore import *
    from PySide2.QtGui import *
    from PySide2.QtWidgets import *
    


  • Hi @martinvej

    Is it WINDOWS? 16 ms ist the timer granularity on WINDOWS. That may have nothing to do with the graphics view (if it has simple enough contents).

    -Michael.



  • @m.sue I'm currently running this on macOS (El Capitan). My biggest concern is that if I have 3 or 4 QGraphicsScenes that are all tied to my animation, their total update time would be around 64 msec, which leaves me at < 16 fps.



  • Figured out this wouldn't get any faster, as it is tied to the refresh rate of the monitor (60Hz) and since vsync is turned on by default, a gui update can't happen at a faster rate. Is there any way to lock/ unlock gui updates?


  • Qt Champions 2016

    @martinvej

    Hi most gfx card can turn off Vsync
    Not that screen can draw any faster regardless but it allows u to puch more frames.


  • Lifetime Qt Champion

    Hi,

    To get any faster you'll likely have to consider going OpenGL.

    What kind of animation do you have ? And do you really need to reach 120fps ?



  • @SGaist
    Thanks for suggesting OpenGL, I think that might be a possibility at some point.
    As of now, I got it to work by locking the UI updates and batch repainting all of the windows at once:

    for(auto widget : qApp->topLevelWidgets()){
        widget->setUpdatesEnabled(true);
    }
    qApp->processEvents();
    for(auto widget : qApp->topLevelWidgets()){
        widget->setUpdatesEnabled(false);
    }
    

    I know this may not be the best way to achieve this, so I am all ears if there's any better way to limit UI updates to a single point in execution.
    Thanks!



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