from PyQt6.QtWidgets import QWidget, QStackedWidget, QVBoxLayout from PyQt6.QtCore import QPropertyAnimation, QParallelAnimationGroup, QEasingCurve, Qt, QPoint from .theme import Theme, Colors from .theme_manager import ThemeManager from .style_constants import StyleConstants class BasePage(QWidget): """Базовый класс для страниц""" def __init__(self, parent=None): super().__init__(parent) self.theme_manager = ThemeManager.get_instance() self.setup_base_ui() def setup_base_ui(self): """Настройка базового UI""" colors = self.theme_manager.current_theme.get_colors() self.setStyleSheet(f""" QWidget {{ background-color: {colors['background']}; }} """) self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) # Создаем анимации self.enter_animation = QPropertyAnimation(self, b"pos") self.enter_animation.setDuration(250) self.enter_animation.setEasingCurve(QEasingCurve.Type.OutCubic) self.exit_animation = QPropertyAnimation(self, b"pos") self.exit_animation.setDuration(250) self.exit_animation.setEasingCurve(QEasingCurve.Type.OutCubic) def enter_animation(self): """Анимация появления страницы""" # Создаем группу анимаций self.anim_group = QParallelAnimationGroup() # Анимация прозрачности fade_anim = QPropertyAnimation(self, b"windowOpacity") fade_anim.setStartValue(0.0) fade_anim.setEndValue(1.0) fade_anim.setDuration(200) fade_anim.setEasingCurve(QEasingCurve.Type.OutCubic) # Анимация сдвига pos_anim = QPropertyAnimation(self, b"pos") start_pos = self.pos() pos_anim.setStartValue(start_pos + QPoint(20, 0)) pos_anim.setEndValue(start_pos) pos_anim.setDuration(200) pos_anim.setEasingCurve(QEasingCurve.Type.OutCubic) # Добавляем анимации в группу self.anim_group.addAnimation(fade_anim) self.anim_group.addAnimation(pos_anim) # Запускаем анимацию self.anim_group.start() def leave_animation(self): """Анимация исчезновения страницы""" # Создаем группу анимаций self.anim_group = QParallelAnimationGroup() # Анимация прозрачности fade_anim = QPropertyAnimation(self, b"windowOpacity") fade_anim.setStartValue(1.0) fade_anim.setEndValue(0.0) fade_anim.setDuration(200) fade_anim.setEasingCurve(QEasingCurve.Type.InCubic) # Анимация сдвига pos_anim = QPropertyAnimation(self, b"pos") start_pos = self.pos() pos_anim.setStartValue(start_pos) pos_anim.setEndValue(start_pos - QPoint(20, 0)) pos_anim.setDuration(200) pos_anim.setEasingCurve(QEasingCurve.Type.InCubic) # Добавляем анимации в группу self.anim_group.addAnimation(fade_anim) self.anim_group.addAnimation(pos_anim) # Запускаем анимацию self.anim_group.start() class PageContainer(QStackedWidget): """Контейнер для страниц с анимацией переходов""" def __init__(self, parent=None): super().__init__(parent) self.pages = {} self.current_page = None def add_page(self, name: str, page: BasePage): """Добавить страницу""" self.pages[name] = page self.addWidget(page) def show_page(self, name: str): """Показать страницу с анимацией""" if name not in self.pages: return next_page = self.pages[name] if self.current_page == next_page: return # Получаем размеры виджета width = self.width() # Настраиваем анимации if self.current_page: # Анимация выхода текущей страницы self.current_page.exit_animation.setStartValue(QPoint(0, 0)) self.current_page.exit_animation.setEndValue(QPoint(-width, 0)) self.current_page.exit_animation.start() # Анимация входа следующей страницы next_page.move(width, 0) next_page.enter_animation.setStartValue(QPoint(width, 0)) next_page.enter_animation.setEndValue(QPoint(0, 0)) next_page.enter_animation.start() # Показываем страницу self.setCurrentWidget(next_page) self.current_page = next_page