使用 QPropretyAnimation 为自定义 QGraphicsItem 设置动画

Posted

技术标签:

【中文标题】使用 QPropretyAnimation 为自定义 QGraphicsItem 设置动画【英文标题】:Animating a custom QGraphicsItem with QPropretyAnimation 【发布时间】:2013-03-31 11:01:33 【问题描述】:

我想让汽车跟随路径,所以我尝试使用 QPropreties 为自定义 QGraphicsItem(描述“汽车”)设置动画,从 PySide 文档中给出的示例开始:

  self.anim = QtCore.QPropertyAnimation(self.car, "geometry")
  self.anim.setDuration(4000);
  self.anim.setStartValue(QtCore.QRect(0, 0, 100, 30));
  self.anim.setEndValue(QtCore.QRect(250, 250, 100, 30));
  self.anim.start();

self.car 这里是 Car 的一个实例,这是一个继承自 QGraphicsItemQObject 的类(EDIT 对此进行了更改,参见 EDIT 2):

class Car(QtGui.QGraphicsItem, QtCore.QObject):

        def __init__(self, map = None, ....):

            super(Car, self).__init__()
            self.map = map
                    ....

执行此操作时,我总是得到相同的错误代码:

  QPropertyAnimation::updateState (geometry): Changing state of an animation without target

这很奇怪,因为目标确实设定了!我试着把 setTargetObject (见documentation on PySide),但它没有改变任何东西。

知道这可能来自哪里吗?

编辑: 有帮助的东西 -> 我试着把这三行放在里面,结果表明没有考虑到对象:

  print self.car
  self.anim.setTargetObject(self.car)
  print self.anim.targetObject()

结果

<engine.Car(this = 0x43f9200 , parent = 0x0 , pos = QPointF(0, 0) , z = 0 , flags =  ( ItemIsMovable | ItemIsSelectable ) )  at 0x1de0368>
None

编辑 2: 将类继承更改为 QGraphicsObject 似乎已经解决了“无目标”问题!但是我现在有一个不同的错误(使用自定义属性'pos'):

  QPropertyAnimation::updateState (pos, Car, ): starting an animation without end value

我是这样定义我的财产的:

def setPos(self, pos):
    self.x = pos[0]
    self.y = pos[1]
    self.update()

def readPos(self):
    return (self.x, self.y)

pp = QtCore.Property('tuple', readPos, setPos)

【问题讨论】:

QGraphicsItem 没有几何属性。您可能想要为boundingRect 设置动画(我认为这是不可能的),或者您自己创建的其他一些属性来控制您绘制汽车的大小。 【参考方案1】:

如果您只需要动画位置,您可以动画GraphicsItem.pos 而不是定义自己的位置函数(除非您希望汽车在QGraphicsItem 本身内有一个位置。

至于'starting an animation without end value',请确保:

    在动画上调用setEndValue。 将正确的类型传递给setEndValue(例如,您当前的实现需要一个元组,使用GraphicsItem.pos 需要一个QPoint)。

【讨论】:

谢谢,在尝试修复这个问题时,我注意到所有 GraphicsItem(以及 GraphicsObject)中已经有一个“pos”属性。我使用原生位置属性重新实现了我的类,它终于动画了! (不幸的是动画很奇怪,位置值有一个偏移量......但我在重新实现我的课程时一定搞砸了)。谢谢!【参考方案2】:

解决方案是首先将继承从QGraphicsItemQObject 更改为QGraphicsObject。然后,我犯的第二个错误是我没有正确定义我的属性(x 和 y)。

我最终重新实现了我的类以使用 QGraphicsObject 的“pos”属性并为其提供正确的开始和结束值(元组)。

【讨论】:

你知道为什么从 QGraphicsItem 和 QObject 继承是不好的吗?财产的定义有什么问题。我偶然发现了同样的错误并希望解决它。 其实 QGraphicsObject 只是 QGraphicsItem + 一些信号和属性。 (因为它已经从 QObject 继承并定义了旋转、位置等的正确属性)。来自 Qt 文档:“QGraphicsObject 类为所有需要信号、槽和属性的图形项提供了一个基类。”

以上是关于使用 QPropretyAnimation 为自定义 QGraphicsItem 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

WCF 自定义行为的依赖注入

Xamarin.Forms 条目 - 自定义行为和 MVVM

从 Flutter 为 Firebase 身份验证设置自定义声明

将位图图像裁剪为自定义正方形

Xcode 9:好奇的自定义字体行为

Oracle 的用户自定义聚合函数可以定义为与两列一起使用吗?