在 QGraphicsScene 中移动 QGraphicItems 的有效方法 [英] Efficient way to move QGraphicItems inside QGraphicsScene

查看:76
本文介绍了在 QGraphicsScene 中移动 QGraphicItems 的有效方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 pyqt5 开发视频播放器.我在场景中使用 QGraphicsVideoItem.在这个视频项目之上,我还需要在每个新帧上有一些在场景中移动的多边形.他们跟踪视频中的内容.理想情况下,我不想让它们以 30 fps 的速度移动.我进行了一次测试,以 30 fps 的速度将 1 个多边形移动了 1 个像素.我用 QGraphicsPolygonItem 中的 setPos() 函数做到了这一点.这是有效的,但它非常不稳定,每次多边形在重新粉刷之前您都可以看到它闪烁白色.我认为这是因为我移动得太快了.此外,此操作在一个线程中并行运行.

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 each new frame. They track things in the video. Ideally I wan't to get them to move with 30 fps. I did a test run, where I moved 1 polygon by 1 pixel at a speed of 30 fps. I did this with the setPos() function in the QGraphicsPolygonItem. This works, but it is very wonky and each time the polygon you can see it flashing white before being repainted. I think this happens because I am moving it too quickly. Also, this action is running in parallel in a thread.

我想知道的是,当您打开QGraphicsItem.ItemIsSelectable"和QGraphicsItem.ItemIsMovable"标志并手动移动项目时,是否有一种方法可以像移动多边形一样移动多边形.这非常顺利,也是我想要实现的目标.

What I want to know is if there is a way move the polygon the same way it moves when you turn on the "QGraphicsItem.ItemIsSelectable" and "QGraphicsItem.ItemIsMovable" flags and move the item manually. This is very smooth and is what I would like to achieve.

我也尝试让点保持静止,而是移动 QGraphicsVideoitem,这有点奏效(移动更稳定,没有闪烁的白色),但我无法让场景以 videoItem 为中心.我尝试使用setFocus",但这不起作用.

I also tried leaving the points as stationary and instead moving the QGraphicsVideoitem around, this kinda worked (the move was steadier and there was no flashing white) but I could not get the scene to be centered on the videoItem. I tried using "setFocus", but this did not work.

谢谢.

推荐答案

在这些情况下,不建议在每一帧中逐个像素地移动 item,最好每 n 帧移动一次,这样移动就会平滑,因为必须对路线进行插值,因为它可以使用 QVariantAnimation,在以下示例中,每 300 毫秒随机插入一次多边形.

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_())

这篇关于在 QGraphicsScene 中移动 QGraphicItems 的有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆