Skip to content Skip to sidebar Skip to footer

Efficient Way To Move Qgraphicitems Inside Qgraphicsscene

I am developing a video player using pyqt5. I am using QGraphicsVideoItem inside a scene. On top of this videoitem, I also need to have some polygons that move around the scene on

Solution 1:

In these cases it is not advisable to move the item in each frame pixel by pixel, it is better to move every n frames so that the movement is smooth since the route must be interpolated for it can be used QVariantAnimation, in the following example the polygon randomly every 300ms.

import random
from PyQt5 import QtCore, QtGui, QtWidgets

class GraphicsPolygonItem(QtWidgets.QGraphicsPolygonItem):
    def moveTo(self, next_pos, duration=250):
        self._animation = QtCore.QVariantAnimation(
            duration = duration,
            valueChanged = self.setPos,
            startValue = self.pos(),
            endValue = next_pos)
        self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        _scene = QtWidgets.QGraphicsScene(QtCore.QRectF(-250, -250, 500, 500), self)
        self.setScene(_scene)
        self.scene().addRect(self.sceneRect(), brush=QtGui.QBrush(QtCore.Qt.green))
        polygon = QtGui.QPolygonF()
        polygon << QtCore.QPointF( 10, 10 ) << QtCore.QPointF( 0, 90 ) \
                << QtCore.QPointF( 40, 70 ) << QtCore.QPointF( 80, 110 ) \
                << QtCore.QPointF( 70, 20 )

        self._interval = 300

        self.poly_item = GraphicsPolygonItem(polygon)
        self.poly_item.setBrush(QtGui.QBrush(QtCore.Qt.red))
        self.scene().addItem(self.poly_item)
        timer = QtCore.QTimer(self, interval=self._interval, timeout=self.on_timeout)
        timer.start()

    def on_timeout(self):
        p = QtCore.QPointF(
            random.randint(self.sceneRect().left(), self.sceneRect().right()), 
            random.randint(self.sceneRect().top(), self.sceneRect().bottom()))
        self.poly_item.moveTo(p, self._interval)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = GraphicsView()
    w.resize(720, 720)
    w.show()
    sys.exit(app.exec_())

Post a Comment for "Efficient Way To Move Qgraphicitems Inside Qgraphicsscene"