PySide QPropertyAnimation Not Starting

2019-07-23 19:33发布

问题:

The problem is that when I call QPropertyAnimation.start(), nothing happens.

Color is the property I'm animating and button is the class.

class Button(QPushButton):
    def __init__(self,text="",parent=None):
        super(Button,self).__init__(text,parent)
        # ...
        self.innercolor = QColor(200,0,20)

    def setcolor(self,value): self.innercolor = value
    def getcolor(self): return self.innercolor
    color = Property(QColor,getcolor,setcolor)

    def paintEvent(self, event):
        p = QPainter(self)
        p.fillRect(self.rect(),self.color)
        # ...
        p.end()

    def animated(self,value): print "animating"; self.update()

    def enterEvent(self, event):
        ani = QPropertyAnimation(self,"color")
        ani.setStartValue(self.color)
        ani.setEndValue(QColor(0,0,10))
        ani.setDuration(2000)
        ani.valueChanged.connect(self.animated)
        ani.start()
        print ani.state()
        return QPushButton.enterEvent(self, event)

I'm confused because "animating" never prints out, but ani.state() says the animation is running.

I'm not asking to debug my code or anything, but I think there must be something I'm missing, either in my code or in my understanding of the use of QPropertyAnimation.

I've searched google for an answer, but nothing came up, nothing relevant to me anyway. The closest I found was another SO question, but I still couldn't turn that into an answer for myself. I also saw something about a custom interpolator, do I need to make a custom interpolator, if so, how do I do that.

回答1:

Cool code. It almost works, but the animation isn't persisting past the enterEvent (although I don't entirely understand the mechanics.) If you change

ani = QPropertyAnimation(self,"color")

to

self.ani = QPropertyAnimation(self, "color")
# etc

then it will work.



回答2:

I'm confused because "animating" never prints out, but ani.state() says the animation is running.

At the point of the print, the anmiation exists and is running. When Python returns from enterEvent, ani goes out of scope. As there are no other reference to the object, Python garbage collects the object assuming there is no need to maintain an object that is not referenced. Since the object is deleted, the animation never executes.

Thats interesting, I'd love to know why the animation has to be a property of the object.

The accepted answer changes ani to self.ani. This change provides a refrence to the object outside the scope enterEvent. In the corrected code, when enterEvent exits, the object maintains a reference to ani and it is no longer garbage collected due to the additional reference. It exists when Qt returns to the event loop and the animation successfully executes.