icon and splash screen
This commit is contained in:
parent
f2857f2fe6
commit
c2067b2a41
67
app/ui/widgets/loading_spinner.py
Normal file
67
app/ui/widgets/loading_spinner.py
Normal file
@ -0,0 +1,67 @@
|
||||
from PyQt6.QtCore import Qt, QTimer
|
||||
from PyQt6.QtWidgets import QLabel
|
||||
from PyQt6.QtGui import QPainter, QPen
|
||||
from app.core.main_manager import MainManager
|
||||
import math
|
||||
|
||||
class LoadingSpinner(QLabel):
|
||||
def __init__(self, size=40, parent=None):
|
||||
super().__init__(parent)
|
||||
self.size = size
|
||||
self.angle = 0
|
||||
self.setFixedSize(size, size)
|
||||
|
||||
# Timer pour l'animation
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.rotate)
|
||||
self.timer.start(50) # 50ms = rotation fluide
|
||||
|
||||
def rotate(self):
|
||||
self.angle = (self.angle + 10) % 360
|
||||
self.update()
|
||||
|
||||
def paintEvent(self, event):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
|
||||
# Obtenir la couleur du thème
|
||||
main_manager = MainManager.get_instance()
|
||||
theme = main_manager.get_theme_manager().get_theme()
|
||||
color = theme.get_color("background_secondary_color")
|
||||
|
||||
# Dessiner le cercle de chargement
|
||||
rect = self.rect()
|
||||
center_x, center_y = rect.width() // 2, rect.height() // 2
|
||||
radius = min(center_x, center_y) - 5
|
||||
|
||||
painter.translate(center_x, center_y)
|
||||
painter.rotate(self.angle)
|
||||
|
||||
# Dessiner les segments du spinner
|
||||
pen = QPen()
|
||||
pen.setWidth(3)
|
||||
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
|
||||
|
||||
for i in range(8):
|
||||
alpha = 255 - (i * 25) # Dégradé d'opacité
|
||||
pen.setColor(self.hex_to_qcolor(color, alpha))
|
||||
painter.setPen(pen)
|
||||
|
||||
angle = i * 45
|
||||
start_x = radius * 0.7 * math.cos(math.radians(angle))
|
||||
start_y = radius * 0.7 * math.sin(math.radians(angle))
|
||||
end_x = radius * math.cos(math.radians(angle))
|
||||
end_y = radius * math.sin(math.radians(angle))
|
||||
|
||||
painter.drawLine(int(start_x), int(start_y), int(end_x), int(end_y))
|
||||
|
||||
def hex_to_qcolor(self, hex_color, alpha=255):
|
||||
from PyQt6.QtGui import QColor
|
||||
hex_color = hex_color.lstrip('#')
|
||||
r = int(hex_color[0:2], 16)
|
||||
g = int(hex_color[2:4], 16)
|
||||
b = int(hex_color[4:6], 16)
|
||||
return QColor(r, g, b, alpha)
|
||||
|
||||
def stop(self):
|
||||
self.timer.stop()
|
132
app/ui/windows/splash_screen.py
Normal file
132
app/ui/windows/splash_screen.py
Normal file
@ -0,0 +1,132 @@
|
||||
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel
|
||||
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
|
||||
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()
|
||||
|
||||
def __init__(self, duration=3000, parent=None):
|
||||
super().__init__(parent)
|
||||
self.duration = duration
|
||||
|
||||
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.setup_ui()
|
||||
self.setup_timer()
|
||||
|
||||
|
||||
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)
|
||||
|
||||
# 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 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"""
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
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 setup_timer(self):
|
||||
"""Configure le timer pour fermer automatiquement le splash screen"""
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.close_splash)
|
||||
self.timer.start(self.duration)
|
||||
|
||||
def close_splash(self):
|
||||
"""Ferme le splash screen et émet le signal"""
|
||||
if hasattr(self, 'spinner'):
|
||||
self.spinner.stop()
|
||||
self.timer.stop()
|
||||
self.hide()
|
||||
self.finished.emit()
|
||||
|
||||
def show_splash(self):
|
||||
"""Affiche le splash screen"""
|
||||
self.show()
|
||||
self.raise_()
|
||||
self.activateWindow()
|
@ -4,6 +4,7 @@
|
||||
"app_version": "1.0.0",
|
||||
"architecture": "x64",
|
||||
"icon_path": "data/assets/icon.ico",
|
||||
"splash_image": "splash",
|
||||
"main_script": "main.py",
|
||||
"git_repo": "https://gitea.louismazin.ovh/LouisMazin/PythonApplicationTemplate"
|
||||
}
|
BIN
data/assets/icon.icns
Normal file
BIN
data/assets/icon.icns
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
data/assets/splash.png
Normal file
BIN
data/assets/splash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
41
main.py
41
main.py
@ -3,23 +3,52 @@ import app.utils.paths as paths
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
from PyQt6.QtGui import QIcon
|
||||
from app.ui.main_window import MainWindow
|
||||
from app.ui.windows.splash_screen import SplashScreen
|
||||
from app.core.main_manager import MainManager
|
||||
|
||||
def main() -> int:
|
||||
main_manager: MainManager = MainManager.get_instance()
|
||||
theme_manager = main_manager.get_theme_manager()
|
||||
settings_manager = main_manager.get_settings_manager()
|
||||
update_manager = main_manager.get_update_manager() # Ajout
|
||||
update_manager = main_manager.get_update_manager()
|
||||
|
||||
app: QApplication = QApplication(sys.argv)
|
||||
app.setStyleSheet(theme_manager.get_sheet())
|
||||
app.setApplicationName(settings_manager.get_config("app_name"))
|
||||
app.setWindowIcon(QIcon(paths.get_asset_path("icon")))
|
||||
|
||||
if update_manager.check_for_update():
|
||||
return
|
||||
# Vérifier si l'image splash existe
|
||||
splash_image_path = paths.get_asset_path(settings_manager.get_config("splash_image"))
|
||||
use_splash = splash_image_path and paths.Path(splash_image_path).exists()
|
||||
|
||||
window: MainWindow = MainWindow()
|
||||
window.show()
|
||||
if use_splash:
|
||||
# Créer et afficher le splash screen
|
||||
splash = SplashScreen(duration=1500)
|
||||
splash.show_splash()
|
||||
|
||||
# Vérifier les mises à jour en arrière-plan
|
||||
if update_manager.check_for_update():
|
||||
splash.close_splash()
|
||||
return 0
|
||||
|
||||
# Créer la fenêtre principale
|
||||
window: MainWindow = MainWindow()
|
||||
|
||||
# Connecter le signal finished pour afficher la fenêtre principale
|
||||
def show_main_window():
|
||||
splash.close()
|
||||
window.show()
|
||||
|
||||
splash.finished.connect(show_main_window)
|
||||
else:
|
||||
# Pas de splash screen, vérifier directement les mises à jour
|
||||
if update_manager.check_for_update():
|
||||
return 0
|
||||
|
||||
# Créer et afficher directement la fenêtre principale
|
||||
window: MainWindow = MainWindow()
|
||||
window.show()
|
||||
|
||||
app.setStyleSheet(theme_manager.get_sheet())
|
||||
return app.exec()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
x
Reference in New Issue
Block a user