2014-03-31 78 views
1

正如问题中所述,当我尝试使用QGraphicsItemAnimation的setPosAt()函数简单地设置动画圈时,我在终端中收到此警告消息,对于此警告的来源我感到很疑惑。我的代码:在PySide中导致“QTimeLine already running”消息的原因是什么?

def animate(self): 

    # moves item to location smoothly in one second 
    def animate_to(t,item,x,y): 
     # used to animate an item in specific ways 
     animation = QtGui.QGraphicsItemAnimation() 

     # create a timeline (1 sec here) 
     timeline = QtCore.QTimeLine(1000) 
     timeline.setFrameRange(0,100) # 100 steps 

     #item should at 'x,y' by time 't' 
     animation.setPosAt(t,QtCore.QPointF(x,y)) 
     animation.setItem(item)    # animate this item 
     animation.setTimeLine(timeline)  # with this duration/steps 

     return animation 

    self.animations.append(animate_to(1,self.c1,150,150)) 

    [ animation.timeLine().start() for animation in self.animations ] 

    self.animator.start(1000) 

我什么混淆最深的是,此警告消失,当我注释掉一节中的最后一行的事实 - 从我的理解是关系到QTimer,而不是QTimeLine本身。作为参考,这里是唯一处理QTimer的其他代码:

class MainWindow(QMainWindow, Ui_MainWindow): 
def __init__(self, parent=None): 
    super(MainWindow, self).__init__(parent) 
    self.setupUi(self) 

      ... 

    self.animator = QtCore.QTimer() 
    self.animator.timeout.connect(self.animate) 

    self.animate() 

对此警告或任何可能的修复的起源的任何想法?

回答

1

你的代码缩进是有点偏离(顶线应该是缩进?),所以我会用文字总结你的代码,以确认我理解发生了什么。

您致电self.animate()。此方法创建一个动画,并将其附加到列表self.animations。您遍历此列表并开始动画。你启动一个定时器(1秒超时),它调用self.animate()

问题出现是因为每次拨打self.animate()时,self.animations都会增加一个元素。所以旧的动画实例在下次调用该方法时仍在列表中。您正在迭代整个列表以启动动画,因此您在动画上多次调用animator.timeLine().start()

删除对定时器的调用可防止self.animation()方法多次运行,因此,在注释掉该行时,您永远不会遇到问题。

+0

谢谢!你是对的。在我的情况下,因为每次调用函数时都会使用新的动画更新列表'动画',所以我只需在每次迭代开始时清除列表: del self.animations [:] – estebro

+0

@estebro您可能想要考虑通过连接到时间线的'finished()'信号完成清除动画。这样你就不会冒险让你的动画对象过早地被删除(例如,如果下一次迭代恰好在动画完成之前运行)。您可能是好的,但考虑到动画的长度与QTimer的长度相同,您有可能面临这种竞争条件。我会用一个例子更新我的文章。 –

+0

其实,我不会在我的帖子中添加任何内容,因为它变得相当复杂。如果沿着我刚刚签署的路线走,你仍然有可能在给定的时间轴上调用两次'start()',所以你需要在你的方法中添加一个条件,它只启动尚未运行的时间轴(或者只有刚刚创建)。无论如何,我们都有必要考虑未来! –

相关问题