184 lines
5.4 KiB
Python
184 lines
5.4 KiB
Python
|
|
"""
|
|||
|
|
UI动画效果模块
|
|||
|
|
- 渐入渐出
|
|||
|
|
- 滑动效果
|
|||
|
|
- 缩放效果
|
|||
|
|
"""
|
|||
|
|
from PySide6.QtWidgets import QWidget, QGraphicsOpacityEffect
|
|||
|
|
from PySide6.QtCore import (
|
|||
|
|
QPropertyAnimation, QEasingCurve, QParallelAnimationGroup,
|
|||
|
|
QSequentialAnimationGroup, Property, QPoint, QSize
|
|||
|
|
)
|
|||
|
|
from PySide6.QtGui import QColor
|
|||
|
|
|
|||
|
|
from core.config import config
|
|||
|
|
|
|||
|
|
|
|||
|
|
class AnimationMixin:
|
|||
|
|
"""动画混入类,为QWidget添加动画功能"""
|
|||
|
|
|
|||
|
|
def setup_animation(self):
|
|||
|
|
"""初始化动画效果"""
|
|||
|
|
if not hasattr(self, '_opacity_effect'):
|
|||
|
|
self._opacity_effect = QGraphicsOpacityEffect(self)
|
|||
|
|
self._opacity_effect.setOpacity(1.0)
|
|||
|
|
self.setGraphicsEffect(self._opacity_effect)
|
|||
|
|
|
|||
|
|
def fade_in(self, duration: int = None, callback=None):
|
|||
|
|
"""渐入动画"""
|
|||
|
|
if not config.get("animation_enabled", True):
|
|||
|
|
if callback:
|
|||
|
|
callback()
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
self.setup_animation()
|
|||
|
|
duration = duration or config.get("animation_duration", 300)
|
|||
|
|
|
|||
|
|
self._opacity_effect.setOpacity(0)
|
|||
|
|
self.show()
|
|||
|
|
|
|||
|
|
self._fade_anim = QPropertyAnimation(self._opacity_effect, b"opacity")
|
|||
|
|
self._fade_anim.setDuration(duration)
|
|||
|
|
self._fade_anim.setStartValue(0.0)
|
|||
|
|
self._fade_anim.setEndValue(1.0)
|
|||
|
|
self._fade_anim.setEasingCurve(QEasingCurve.Type.OutCubic)
|
|||
|
|
|
|||
|
|
if callback:
|
|||
|
|
self._fade_anim.finished.connect(callback)
|
|||
|
|
|
|||
|
|
self._fade_anim.start()
|
|||
|
|
|
|||
|
|
def fade_out(self, duration: int = None, callback=None):
|
|||
|
|
"""渐出动画"""
|
|||
|
|
if not config.get("animation_enabled", True):
|
|||
|
|
self.hide()
|
|||
|
|
if callback:
|
|||
|
|
callback()
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
self.setup_animation()
|
|||
|
|
duration = duration or config.get("animation_duration", 300)
|
|||
|
|
|
|||
|
|
self._fade_anim = QPropertyAnimation(self._opacity_effect, b"opacity")
|
|||
|
|
self._fade_anim.setDuration(duration)
|
|||
|
|
self._fade_anim.setStartValue(1.0)
|
|||
|
|
self._fade_anim.setEndValue(0.0)
|
|||
|
|
self._fade_anim.setEasingCurve(QEasingCurve.Type.InCubic)
|
|||
|
|
|
|||
|
|
def on_finished():
|
|||
|
|
self.hide()
|
|||
|
|
self._opacity_effect.setOpacity(1.0)
|
|||
|
|
if callback:
|
|||
|
|
callback()
|
|||
|
|
|
|||
|
|
self._fade_anim.finished.connect(on_finished)
|
|||
|
|
self._fade_anim.start()
|
|||
|
|
|
|||
|
|
|
|||
|
|
def create_fade_animation(widget: QWidget, fade_in: bool = True, duration: int = None) -> QPropertyAnimation:
|
|||
|
|
"""创建渐变动画"""
|
|||
|
|
if not config.get("animation_enabled", True):
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
duration = duration or config.get("animation_duration", 300)
|
|||
|
|
|
|||
|
|
# 确保有透明度效果
|
|||
|
|
effect = widget.graphicsEffect()
|
|||
|
|
if not isinstance(effect, QGraphicsOpacityEffect):
|
|||
|
|
effect = QGraphicsOpacityEffect(widget)
|
|||
|
|
widget.setGraphicsEffect(effect)
|
|||
|
|
|
|||
|
|
anim = QPropertyAnimation(effect, b"opacity")
|
|||
|
|
anim.setDuration(duration)
|
|||
|
|
|
|||
|
|
if fade_in:
|
|||
|
|
anim.setStartValue(0.0)
|
|||
|
|
anim.setEndValue(1.0)
|
|||
|
|
anim.setEasingCurve(QEasingCurve.Type.OutCubic)
|
|||
|
|
else:
|
|||
|
|
anim.setStartValue(1.0)
|
|||
|
|
anim.setEndValue(0.0)
|
|||
|
|
anim.setEasingCurve(QEasingCurve.Type.InCubic)
|
|||
|
|
|
|||
|
|
return anim
|
|||
|
|
|
|||
|
|
|
|||
|
|
def create_slide_animation(widget: QWidget, start_pos: QPoint, end_pos: QPoint,
|
|||
|
|
duration: int = None) -> QPropertyAnimation:
|
|||
|
|
"""创建滑动动画"""
|
|||
|
|
if not config.get("animation_enabled", True):
|
|||
|
|
widget.move(end_pos)
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
duration = duration or config.get("animation_duration", 300)
|
|||
|
|
|
|||
|
|
anim = QPropertyAnimation(widget, b"pos")
|
|||
|
|
anim.setDuration(duration)
|
|||
|
|
anim.setStartValue(start_pos)
|
|||
|
|
anim.setEndValue(end_pos)
|
|||
|
|
anim.setEasingCurve(QEasingCurve.Type.OutCubic)
|
|||
|
|
|
|||
|
|
return anim
|
|||
|
|
|
|||
|
|
|
|||
|
|
def animate_widget_show(widget: QWidget, direction: str = "fade"):
|
|||
|
|
"""显示控件动画"""
|
|||
|
|
if not config.get("animation_enabled", True):
|
|||
|
|
widget.show()
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
duration = config.get("animation_duration", 300)
|
|||
|
|
|
|||
|
|
if direction == "fade":
|
|||
|
|
effect = QGraphicsOpacityEffect(widget)
|
|||
|
|
effect.setOpacity(0)
|
|||
|
|
widget.setGraphicsEffect(effect)
|
|||
|
|
widget.show()
|
|||
|
|
|
|||
|
|
anim = QPropertyAnimation(effect, b"opacity")
|
|||
|
|
anim.setDuration(duration)
|
|||
|
|
anim.setStartValue(0.0)
|
|||
|
|
anim.setEndValue(1.0)
|
|||
|
|
anim.setEasingCurve(QEasingCurve.Type.OutCubic)
|
|||
|
|
anim.start()
|
|||
|
|
|
|||
|
|
# 保持引用
|
|||
|
|
widget._show_anim = anim
|
|||
|
|
else:
|
|||
|
|
widget.show()
|
|||
|
|
|
|||
|
|
|
|||
|
|
def animate_widget_hide(widget: QWidget, callback=None):
|
|||
|
|
"""隐藏控件动画"""
|
|||
|
|
if not config.get("animation_enabled", True):
|
|||
|
|
widget.hide()
|
|||
|
|
if callback:
|
|||
|
|
callback()
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
duration = config.get("animation_duration", 300)
|
|||
|
|
|
|||
|
|
effect = widget.graphicsEffect()
|
|||
|
|
if not isinstance(effect, QGraphicsOpacityEffect):
|
|||
|
|
effect = QGraphicsOpacityEffect(widget)
|
|||
|
|
widget.setGraphicsEffect(effect)
|
|||
|
|
|
|||
|
|
anim = QPropertyAnimation(effect, b"opacity")
|
|||
|
|
anim.setDuration(duration)
|
|||
|
|
anim.setStartValue(1.0)
|
|||
|
|
anim.setEndValue(0.0)
|
|||
|
|
anim.setEasingCurve(QEasingCurve.Type.InCubic)
|
|||
|
|
|
|||
|
|
def on_finished():
|
|||
|
|
widget.hide()
|
|||
|
|
effect.setOpacity(1.0)
|
|||
|
|
if callback:
|
|||
|
|
callback()
|
|||
|
|
|
|||
|
|
anim.finished.connect(on_finished)
|
|||
|
|
anim.start()
|
|||
|
|
|
|||
|
|
# 保持引用
|
|||
|
|
widget._hide_anim = anim
|
|||
|
|
|