在qgraphicscen中移动qgraphicsitems的有效方法

2024-09-28 20:18:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个视频播放器使用pyqt5。我在场景中使用QGraphicsVideoItem。在这个视频项目的顶部,我还需要有一些多边形,在每个新帧的场景周围移动。他们追踪录像里的东西。理想情况下我不想让他们以每秒30帧的速度移动。我做了一个测试运行,我移动了1个多边形1像素的速度为30帧/秒。我是用QGraphicsPolygonItem中的setPos()函数完成的。这是可行的,但它是非常不稳定的,每次多边形你可以看到它闪烁白色之前被重新粉刷。我想这是因为我移动太快了。此外,此操作在线程中并行运行。你知道吗

我想知道的是,是否有一种方法可以让多边形像你打开QGraphicsItem.items可选“和”QGraphicsItem.ItemIsMovable“手动标记和移动项目。这是非常顺利,是我想达到的。你知道吗

我也试着让点保持静止,而不是移动QGraphicsVideoitem,这有点奏效(移动更平稳,没有闪烁的白色),但我无法使场景集中在视频项上。我试过使用“setFocus”,但没有成功。你知道吗

谢谢你。你知道吗


Tags: 项目视频场景情况像素多边形播放器速度
1条回答
网友
1楼 · 发布于 2024-09-28 20:18:59

在这些情况下,不建议逐像素移动每帧中的项目,最好每n帧移动一次,以便移动平滑,因为必须对路径进行插值,以便使用QVariantAnimation,在下面的示例中,多边形每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_())

相关问题 更多 >