generated from LouisMazin/PythonApplicationTemplate
159 lines
6.3 KiB
Python
159 lines
6.3 KiB
Python
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QApplication
|
|
from PyQt6.QtCore import Qt, pyqtSignal, QTimer
|
|
from PyQt6.QtGui import QPixmap
|
|
from app.core.main_manager import MainManager
|
|
from app.ui.widgets.loading_spinner import LoadingSpinner
|
|
import app.utils.paths as paths
|
|
|
|
class SplashScreen(QWidget):
|
|
finished = pyqtSignal(bool) # True si succès, False si échec/interruption
|
|
|
|
def __init__(self, parent=None, preload_function=None):
|
|
super().__init__(parent)
|
|
self.preload_function = preload_function
|
|
self.preload_result = True
|
|
|
|
self.main_manager = MainManager.get_instance()
|
|
self.theme_manager = self.main_manager.get_theme_manager()
|
|
self.settings_manager = self.main_manager.get_settings_manager()
|
|
self.language_manager = self.main_manager.get_language_manager()
|
|
|
|
self.setup_ui()
|
|
if self.preload_function:
|
|
self.start_preloading()
|
|
else:
|
|
# Pas de préchargement, fermer immédiatement
|
|
QTimer.singleShot(100, lambda: self.finished.emit(True))
|
|
|
|
def setup_ui(self):
|
|
# Configuration de la fenêtre
|
|
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint)
|
|
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
self.setFixedSize(800, 600)
|
|
|
|
# Layout principal
|
|
layout = QVBoxLayout(self)
|
|
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
layout.setSpacing(60)
|
|
layout.setContentsMargins(80, 80, 80, 80)
|
|
|
|
# Image splash
|
|
self.image_label = QLabel()
|
|
self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.load_splash_image()
|
|
layout.addWidget(self.image_label)
|
|
|
|
# Texte de progression
|
|
self.progress_label = QLabel("Chargement...")
|
|
self.progress_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
self.progress_label.setStyleSheet("font-size: 14px; color: #666;")
|
|
layout.addWidget(self.progress_label)
|
|
|
|
# Spinner de chargement
|
|
self.spinner = LoadingSpinner(50, self)
|
|
spinner_layout = QVBoxLayout()
|
|
spinner_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
spinner_layout.addWidget(self.spinner)
|
|
layout.addLayout(spinner_layout)
|
|
|
|
# Appliquer le thème
|
|
self.apply_theme()
|
|
|
|
# Centrer la fenêtre
|
|
self.center_on_screen()
|
|
|
|
def start_preloading(self):
|
|
"""Démarre le préchargement avec un délai pour permettre l'affichage du splash"""
|
|
# Laisser le temps au splash de s'afficher
|
|
QTimer.singleShot(200, self.do_preloading)
|
|
|
|
def do_preloading(self):
|
|
"""Effectue le préchargement dans le thread principal"""
|
|
try:
|
|
# Fonction callback pour mettre à jour le texte
|
|
def progress_callback(text):
|
|
self.progress_label.setText(text)
|
|
# Traiter les événements pour que l'UI se mette à jour
|
|
QApplication.processEvents()
|
|
|
|
# Appeler la fonction de préchargement
|
|
success = self.preload_function(progress_callback)
|
|
self.preload_result = success
|
|
|
|
except Exception:
|
|
self.preload_result = False
|
|
|
|
# Attendre un peu puis fermer
|
|
QTimer.singleShot(300, self.close_splash)
|
|
|
|
def close_splash(self):
|
|
"""Ferme le splash screen et émet le signal"""
|
|
if hasattr(self, 'spinner'):
|
|
self.spinner.stop()
|
|
self.finished.emit(self.preload_result)
|
|
self.close()
|
|
|
|
def load_splash_image(self):
|
|
"""Charge l'image splash depuis la config"""
|
|
try:
|
|
splash_image_path = paths.get_asset_path(self.settings_manager.get_config("splash_image"))
|
|
if splash_image_path:
|
|
# Essayer le chemin depuis la config
|
|
if not splash_image_path.startswith('/') and not splash_image_path.startswith('\\') and ':' not in splash_image_path:
|
|
# Chemin relatif, le résoudre depuis le dossier assets
|
|
splash_image_path = paths.get_asset_path(splash_image_path)
|
|
|
|
pixmap = QPixmap(splash_image_path)
|
|
if not pixmap.isNull():
|
|
# Redimensionner l'image
|
|
scaled_pixmap = pixmap.scaled(400, 300, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
|
|
self.image_label.setPixmap(scaled_pixmap)
|
|
return
|
|
|
|
# Fallback : essayer l'icône par défaut
|
|
fallback_path = paths.get_asset_path("icon.png")
|
|
pixmap = QPixmap(fallback_path)
|
|
if not pixmap.isNull():
|
|
scaled_pixmap = pixmap.scaled(240, 240, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
|
|
self.image_label.setPixmap(scaled_pixmap)
|
|
else:
|
|
# Dernier fallback : texte
|
|
self.image_label.setText("🚀")
|
|
self.image_label.setStyleSheet("font-size: 48px;")
|
|
except Exception:
|
|
# En cas d'erreur, afficher un emoji
|
|
self.image_label.setText("🚀")
|
|
self.image_label.setStyleSheet("font-size: 48px;")
|
|
|
|
def apply_theme(self):
|
|
"""Applique le thème actuel"""
|
|
theme = self.theme_manager.get_theme()
|
|
|
|
style = f"""
|
|
QWidget {{
|
|
background-color: {theme.get_color("background_color")};
|
|
border-radius: 15px;
|
|
border: 2px solid {theme.get_color("primary_color")};
|
|
}}
|
|
QLabel {{
|
|
color: {theme.get_color("text_color")};
|
|
background: transparent;
|
|
border: none;
|
|
}}
|
|
"""
|
|
self.setStyleSheet(style)
|
|
|
|
def center_on_screen(self):
|
|
"""Centre la fenêtre sur l'écran"""
|
|
screen = QApplication.primaryScreen()
|
|
screen_geometry = screen.geometry()
|
|
|
|
x = (screen_geometry.width() - self.width()) // 2
|
|
y = (screen_geometry.height() - self.height()) // 2
|
|
self.move(x, y)
|
|
|
|
def show_splash(self):
|
|
"""Affiche le splash screen"""
|
|
self.show()
|
|
self.raise_()
|
|
self.activateWindow() |