168 lines
6.4 KiB
Python
168 lines
6.4 KiB
Python
from PySide6.QtCore import (QPropertyAnimation, QParallelAnimationGroup,
|
||
QPoint, QEasingCurve, QTimer)
|
||
from PySide6.QtWidgets import QGraphicsOpacityEffect
|
||
|
||
class MultiStageAnimations:
|
||
def __init__(self, ui):
|
||
self.ui = ui
|
||
# 获取画布尺寸
|
||
self.canvas_width = ui.centralwidget.width()
|
||
self.canvas_height = ui.centralwidget.height()
|
||
|
||
# 动画时序配置
|
||
self.animation_config = {
|
||
"logo": {
|
||
"delay_after": 2800
|
||
},
|
||
"mainbg": {
|
||
"delay_after": 500
|
||
}
|
||
}
|
||
|
||
# 第一阶段:Logo动画配置
|
||
self.logo_widgets = [
|
||
{"widget": ui.vol1bg, "delay": 0, "duration": 500, "end_pos": QPoint(0, 120)},
|
||
{"widget": ui.vol2bg, "delay": 80, "duration": 500, "end_pos": QPoint(0, 180)},
|
||
{"widget": ui.vol3bg, "delay": 160, "duration": 500, "end_pos": QPoint(0, 240)},
|
||
{"widget": ui.vol4bg, "delay": 240, "duration": 500, "end_pos": QPoint(0, 300)},
|
||
{"widget": ui.afterbg, "delay": 320, "duration": 500, "end_pos": QPoint(0, 360)}
|
||
]
|
||
|
||
# 第二阶段:菜单元素
|
||
self.menu_widgets = [
|
||
{"widget": ui.menubg, "end_pos": QPoint(710, 0), "duration": 600},
|
||
{"widget": ui.start_install_btn, "end_pos": QPoint(780, 250), "duration": 600},
|
||
{"widget": ui.exit_btn, "end_pos": QPoint(780, 340), "duration": 600}
|
||
]
|
||
|
||
self.animations = []
|
||
self.timers = []
|
||
def initialize(self):
|
||
"""初始化所有组件状态"""
|
||
# 设置Mainbg初始状态
|
||
effect = QGraphicsOpacityEffect(self.ui.Mainbg)
|
||
effect.setOpacity(0)
|
||
self.ui.Mainbg.setGraphicsEffect(effect)
|
||
|
||
# 初始化Logo位置(移到左侧外)
|
||
for item in self.logo_widgets:
|
||
widget = item["widget"]
|
||
effect = QGraphicsOpacityEffect(widget)
|
||
effect.setOpacity(0)
|
||
widget.setGraphicsEffect(effect)
|
||
widget.move(-widget.width(), item["end_pos"].y())
|
||
widget.show()
|
||
print("初始化支持栏动画")
|
||
|
||
# 初始化菜单元素(底部外)
|
||
for item in self.menu_widgets:
|
||
widget = item["widget"]
|
||
effect = QGraphicsOpacityEffect(widget)
|
||
effect.setOpacity(0)
|
||
widget.setGraphicsEffect(effect)
|
||
widget.move(widget.x(), self.canvas_height + 100)
|
||
widget.show()
|
||
|
||
def start_logo_animations(self):
|
||
"""启动Logo动画序列"""
|
||
for item in self.logo_widgets:
|
||
timer = QTimer()
|
||
timer.setSingleShot(True)
|
||
timer.timeout.connect(
|
||
lambda w=item["widget"], d=item["duration"], pos=item["end_pos"]:
|
||
self.animate_logo(w, pos, d)
|
||
)
|
||
timer.start(item["delay"])
|
||
self.timers.append(timer)
|
||
|
||
def animate_logo(self, widget, end_pos, duration):
|
||
"""执行单个Logo动画"""
|
||
anim_group = QParallelAnimationGroup()
|
||
|
||
# 位置动画
|
||
pos_anim = QPropertyAnimation(widget, b"pos")
|
||
pos_anim.setDuration(duration)
|
||
pos_anim.setStartValue(QPoint(-widget.width(), end_pos.y()))
|
||
pos_anim.setEndValue(end_pos)
|
||
pos_anim.setEasingCurve(QEasingCurve.OutBack)
|
||
|
||
# 透明度动画
|
||
opacity_anim = QPropertyAnimation(widget.graphicsEffect(), b"opacity")
|
||
opacity_anim.setDuration(duration)
|
||
opacity_anim.setStartValue(0)
|
||
opacity_anim.setEndValue(1)
|
||
|
||
anim_group.addAnimation(pos_anim)
|
||
anim_group.addAnimation(opacity_anim)
|
||
|
||
# 最后一个Logo动画完成后添加延迟
|
||
if widget == self.logo_widgets[-1]["widget"]:
|
||
anim_group.finished.connect(
|
||
lambda: QTimer.singleShot(
|
||
self.animation_config["logo"]["delay_after"],
|
||
self.start_mainbg_animation
|
||
)
|
||
)
|
||
|
||
anim_group.start()
|
||
self.animations.append(anim_group)
|
||
|
||
def start_mainbg_animation(self):
|
||
"""启动主背景淡入动画"""
|
||
main_anim = QPropertyAnimation(self.ui.Mainbg.graphicsEffect(), b"opacity")
|
||
main_anim.setDuration(800)
|
||
main_anim.setStartValue(0)
|
||
main_anim.setEndValue(1)
|
||
main_anim.finished.connect(self.start_menu_animations)
|
||
main_anim.start()
|
||
self.animations.append(main_anim)
|
||
|
||
def start_mainbg_animation(self):
|
||
"""启动主背景淡入动画(带延迟)"""
|
||
main_anim = QPropertyAnimation(self.ui.Mainbg.graphicsEffect(), b"opacity")
|
||
main_anim.setDuration(800)
|
||
main_anim.setStartValue(0)
|
||
main_anim.setEndValue(1)
|
||
main_anim.finished.connect(
|
||
lambda: QTimer.singleShot(
|
||
self.animation_config["mainbg"]["delay_after"],
|
||
self.start_menu_animations
|
||
)
|
||
)
|
||
main_anim.start()
|
||
self.animations.append(main_anim)
|
||
def start_menu_animations(self):
|
||
"""启动菜单动画(从下往上)"""
|
||
for item in self.menu_widgets:
|
||
anim_group = QParallelAnimationGroup()
|
||
|
||
# 位置动画(从下往上)
|
||
pos_anim = QPropertyAnimation(item["widget"], b"pos")
|
||
pos_anim.setDuration(item["duration"])
|
||
pos_anim.setStartValue(QPoint(item["end_pos"].x(), self.canvas_height + 100))
|
||
pos_anim.setEndValue(item["end_pos"])
|
||
pos_anim.setEasingCurve(QEasingCurve.OutBack)
|
||
|
||
# 透明度动画
|
||
opacity_anim = QPropertyAnimation(item["widget"].graphicsEffect(), b"opacity")
|
||
opacity_anim.setDuration(item["duration"])
|
||
opacity_anim.setStartValue(0)
|
||
opacity_anim.setEndValue(1)
|
||
|
||
anim_group.addAnimation(pos_anim)
|
||
anim_group.addAnimation(opacity_anim)
|
||
anim_group.start()
|
||
self.animations.append(anim_group)
|
||
def start_animations(self):
|
||
"""启动完整动画序列"""
|
||
self.clear_animations()
|
||
self.start_logo_animations()
|
||
|
||
def clear_animations(self):
|
||
"""清理所有动画资源"""
|
||
for timer in self.timers:
|
||
timer.stop()
|
||
for anim in self.animations:
|
||
anim.stop()
|
||
self.timers.clear()
|
||
self.animations.clear() |