1

I am running into a problem with the QPropertyAnimation class where if I call the animate method more then once, it skips all of the calls to self.animate and executes the last animation instead of all of them.

I have tried to clear all the Key values of the animation once it's finished with an empty dictionary like this:

self.animation.setKeyValues({})

And I have tried to add a time.sleep() function inbetween the calls of self.animate().

Here is my code so far:

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import QtCore
import sys
from threading import Thread
import win32api

class StartUp:
  def __init__(self) -> None:
    screenWidth, screenHeight = win32api.EnumDisplayMonitors()[0][2][2:]
    
    SIZEX, SIZEY = 200, 100
  
    self.startupLocationX, self.startupLocationY = (screenWidth * .8, screenHeight * .05)
    
    if not isinstance(self.startupLocationX, int) or not isinstance(self.startupLocationY, int):
      self.startupLocationX = round(self.startupLocationX)
      self.startupLocationY = round(self.startupLocationY)
    
    self.startUpApplication = QApplication(sys.argv)
    self.startUpWindow = QMainWindow()

    self.startUpWindow.setWindowTitle("AssistantStarted")
    self.startUpWindow.setGeometry(self.startupLocationX, self.startupLocationY, SIZEX, -100)
    self.startUpWindow.setWindowFlag(QtCore.Qt.FramelessWindowHint)
    self.startUpWindow.setWindowFlag(QtCore.Qt.Tool)
    self.startUpWindow.show()
    
    self.animate(
      self.startUpWindow,
      2000,
      (
        QtCore.QRect(
          self.startupLocationX,
          -100,
          300,
          SIZEY
        ),
        QtCore.QRect(
          self.startupLocationX,
          self.startupLocationY,
          300,
          SIZEY
        )
      ),
      QtCore.QEasingCurve.InOutBack,
    ) # Create animation for notification to come down from top right

    self.animate(
      self.startUpWindow,
      2000,
      (
        QtCore.QRect(
          self.startupLocationX,
          self.startupLocationY,
          300,
          SIZEY
        ),
        QtCore.QRect(
          self.startupLocationX,
          -100,
          300,
          SIZEY
        )
      ),
      QtCore.QEasingCurve.InOutBack,
    ) # Make Window go back off the screen 

    sys.exit(self.startUpApplication.exec_())

  def animate(self, parent, duration: int, startToEndPosition: tuple, easingCurve: QtCore.QEasingCurve=None): 
    self.animation = QtCore.QPropertyAnimation(parent, b"geometry")
    self.animation.setStartValue(startToEndPosition[0])
    self.animation.setEndValue(startToEndPosition[1])
    self.animation.setDuration(duration)
    self.animation.setEasingCurve(easingCurve)
    self.animation.start()


if __name__ == "__main__": 
  StartUp()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Nah
  • 189
  • 1
  • 11

1 Answers1

1

It looks like you need to use a sequential animation group. I can't test your example code, but something like this should work:

class StartUp:
  def __init__(self) -> None:
    ...
    
    self.animationGroup = QtCore.QSequentialAnimationGroup(self)

    self.animate(
    ...
    ) # Create animation for notification to come down from top right

    self.animate(
    ...
    ) # Make Window go back off the screen

    self.animationGroup.start()

  def animate(self, parent, duration: int, startToEndPosition: tuple, easingCurve: QtCore.QEasingCurve=None):
    animation = QtCore.QPropertyAnimation(parent, b"geometry")
    animation.setStartValue(startToEndPosition[0])
    animation.setEndValue(startToEndPosition[1])
    animation.setDuration(duration)
    animation.setEasingCurve(easingCurve)
    self.animationGroup.addAnimation(animation)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336