Проблема в том, что «анимация» является локальной переменной, поэтому она будет исключена, когда завершит выполнение создавшая ее функция, в вашем случае, когда она завершит выполнение «перемещения», которое является мгновенным после запуска анимации.
Чтобы понять это, мы можем использовать следующий пример, поскольку QPropertyAnimation является объектом QObject, у него есть сигнал уничтожения, который указывает, когда уничтожается объект QObject.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.box = QtWidgets.QPushButton("QPushButton", self)
def move(self, pos):
animation = QtCore.QPropertyAnimation(self.box, b"pos")
animation.setStartValue(self.box.pos())
animation.setEndValue(pos)
animation.setDuration(20)
animation.start()
animation.destroyed.connect(lambda obj: print("destroyed", obj))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
w.move(QtCore.QPoint(40, 40))
sys.exit(app.exec_())
Вывод:
destroyed <PyQt5.QtCore.QObject object at 0x7f412abffd70>
Таким образом, решение в целом состоит в том, что оно не устраняется, по крайней мере, до окончания анимации, для этого есть несколько вариантов:
Сделать его атрибутом класса, так каку него будет тот же жизненный цикл, что и у класса, и этот метод вы использовали.
Поскольку QPropertyAnimation является объектом QObject, то один из способов продлить жизненный цикл - передать емуродитель, но в этом случае лучше уничтожить его, как только анимация закончится:
def move(self, direction):
animation = QPropertyAnimation(self.box, b'geometry', <b>parent=self</b>)
# ...
animation.start(<b>QPropertyAnimation.DeleteWhenStopped</b>)
animation.finished.connect(lambda: self.move(direction))