Home > OS >  Qt remove a key value from an animation
Qt remove a key value from an animation

Time:12-01

I'm using Qt's Python binding to develop an application. I made a nonlinear animation by setting custom key values, as said in Qt docs:

It is also possible to set values situated between the start and end value. The interpolation will then go by these points.

QPushButton button("Animated Button");
button.show();

QPropertyAnimation animation(&button, "geometry");
animation.setDuration(10000);

animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
animation.setKeyValueAt(1, QRect(0, 0, 100, 30));

animation.start();

Goal

I update my animation values and use it in several sections, and I want to make it linear sometimes.

Problem

I can't find a way to remove an animation's set key values in order to make it linear. I tried setting "startValue" "endValue" to my animation but they just replace the default animation key values (0.0 and 1.0) and the custom key value I set before will remain there. Bellow is a sample code:

import sys

from PyQt5.QtCore import QRect, QPoint, QPropertyAnimation, QParallelAnimationGroup
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFrame


class Form(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.resize(600, 400)
        self.setWindowTitle("Form 1")
        self.frame = QFrame(self)
        self.frame.resize(200, 150)
        self.frame.move(20, 20)
        self.setStyleSheet("""QFrame {
            background-color: orange;
        }""")
        self.button = QPushButton("Start Animation", self)
        self.button.resize(self.button.sizeHint())
        self.button.move(20, 300)
        self.define_animation()
        self.button.clicked.connect(self.frame_anim.start)
        self.show()

    def define_animation(self):
        self.frame_anim = QPropertyAnimation(self.frame, b"geometry")
        self.frame_anim.setDuration(1000)
        self.frame_anim.setStartValue(self.frame.geometry())
        self.frame_anim.setKeyValueAt(0.75, QRect(QPoint(20, 100), self.frame.size()))
        self.frame_anim.setKeyValueAt(1, QRect(QPoint(380, 220), self.frame.size()))
        self.frame_anim.finished.connect(lambda: print("ََAnimation key values", self.frame_anim.keyValues()))
        self.frame_anim.finished.connect(self.define_new_animation)

    def define_new_animation(self):
        self.frame_anim.setStartValue(QRect(QPoint(380, 220), self.frame.size()))
        self.frame_anim.setEndValue(QRect(QPoint(20, 220), self.frame.size()))


app = QApplication(sys.argv)
form = Form()
sys.exit(app.exec_())

The first animation is nonlinear and I set a custom key value, but the next one will keep that key value. I'm looking for a solution to remove a set key value from an animation or any logical way to make it linear after setting custom key values.

CodePudding user response:

Both setStartValue and setEndValue won't "clear" the current animatio, but only set new states for the start and beginnig, while leaving all other nested objects.

If you want to reset it, use setStartValue() with an empty mapping.

In order to update the current animation, you need to clear the existing mapping. This is a possible solution:

class Form(QMainWindow):

    # ...

    def define_new_animation(self):
        self.frame_anim.setKeyValues({})
        self.frame_anim.setStartValue(
            QRect(QPoint(380, 220), self.frame.size()))
        self.frame_anim.setEndValue(
            QRect(QPoint(20, 220), self.frame.size()))
  • Related