Files
nl-tools/ui/animations.py
2025-12-11 09:47:00 +08:00

184 lines
5.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
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