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
|
||
|