Branding CopyDev complet — splash screen, A propos, statusbar

- Splash screen au demarrage (fond sombre, logo CopyDev, nom, coordonnees)
- Statut dans le splash : licence, mise a jour, chargement
- A propos refait : design sombre pro, logo 150px, version, description,
  coordonnees completes (email, web, tel), copyright
- Barre de titre : "CopyDev Imposing Tool vX.X.X — www.copydev.fr"
- Barre de statut : mention "CopyDev — contact@copydev.fr" permanente

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jules
2026-03-20 19:49:23 +01:00
parent 83dc563135
commit e650eb9c68
3 changed files with 146 additions and 20 deletions

View File

@@ -34,7 +34,8 @@ from app.engine.bleeds import define_bleeds
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.setWindowTitle("Copydev Imposing Tool") from app.updater import VERSION
self.setWindowTitle(f"CopyDev Imposing Tool v{VERSION} — www.copydev.fr")
self.setMinimumSize(1000, 700) self.setMinimumSize(1000, 700)
# Icone de la fenetre # Icone de la fenetre
@@ -170,6 +171,9 @@ class MainWindow(QMainWindow):
self._statusbar.addWidget(self._status_label, 1) self._statusbar.addWidget(self._status_label, 1)
self._file_label = QLabel("") self._file_label = QLabel("")
self._statusbar.addPermanentWidget(self._file_label) self._statusbar.addPermanentWidget(self._file_label)
brand = QLabel(" CopyDev — contact@copydev.fr ")
brand.setStyleSheet("color: #64748b; font-size: 10px;")
self._statusbar.addPermanentWidget(brand)
def _on_page_changed(self, page, total): def _on_page_changed(self, page, total):
pass pass
@@ -339,14 +343,16 @@ class MainWindow(QMainWindow):
QMessageBox.critical(self, "Erreur", str(e)) QMessageBox.critical(self, "Erreur", str(e))
def _show_about(self): def _show_about(self):
from PyQt6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDialogButtonBox from PyQt6.QtWidgets import QDialog, QVBoxLayout, QLabel, QDialogButtonBox
from PyQt6.QtGui import QPixmap from PyQt6.QtGui import QPixmap, QFont
from PyQt6.QtCore import Qt from PyQt6.QtCore import Qt
dlg = QDialog(self) dlg = QDialog(self)
dlg.setWindowTitle("A propos") dlg.setWindowTitle("A propos — CopyDev Imposing Tool")
dlg.setFixedSize(480, 380) dlg.setFixedSize(520, 520)
dlg.setStyleSheet("QDialog { background-color: #0f172a; }")
layout = QVBoxLayout(dlg) layout = QVBoxLayout(dlg)
layout.setContentsMargins(40, 30, 40, 25)
# Logo # Logo
logo_label = QLabel() logo_label = QLabel()
@@ -354,60 +360,82 @@ class MainWindow(QMainWindow):
_base = _sys._MEIPASS if getattr(_sys, 'frozen', False) else os.path.dirname(os.path.dirname(os.path.abspath(__file__))) _base = _sys._MEIPASS if getattr(_sys, 'frozen', False) else os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
logo_path = os.path.join(_base, "resources", "logo.png") logo_path = os.path.join(_base, "resources", "logo.png")
if os.path.exists(logo_path): if os.path.exists(logo_path):
pixmap = QPixmap(logo_path).scaled(120, 120, Qt.AspectRatioMode.KeepAspectRatio, pixmap = QPixmap(logo_path).scaled(150, 150, Qt.AspectRatioMode.KeepAspectRatio,
Qt.TransformationMode.SmoothTransformation) Qt.TransformationMode.SmoothTransformation)
logo_label.setPixmap(pixmap) logo_label.setPixmap(pixmap)
logo_label.setAlignment(Qt.AlignmentFlag.AlignCenter) logo_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(logo_label) layout.addWidget(logo_label)
layout.addSpacing(10)
# Titre # Titre
title = QLabel("<h2>Copydev Imposing Tool</h2>") title = QLabel("COPYDEV IMPOSING TOOL")
title.setAlignment(Qt.AlignmentFlag.AlignCenter) title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setFont(QFont("Segoe UI", 20, QFont.Weight.Bold))
title.setStyleSheet("color: white;")
layout.addWidget(title) layout.addWidget(title)
# Version # Version
version = QLabel("Version 1.0.0") from app.updater import VERSION
version = QLabel(f"Version {VERSION}")
version.setAlignment(Qt.AlignmentFlag.AlignCenter) version.setAlignment(Qt.AlignmentFlag.AlignCenter)
version.setStyleSheet("color: #666;") version.setFont(QFont("Segoe UI", 10))
version.setStyleSheet("color: #64748b;")
layout.addWidget(version) layout.addWidget(version)
layout.addSpacing(10) layout.addSpacing(15)
# Description # Description
desc = QLabel( desc = QLabel(
"Outil professionnel d'imposition PDF.\n" "Outil professionnel d'imposition PDF\n"
"Creation de livrets, n-up, repetition, imposition manuelle,\n" "Livrets, n-up, repetition, imposition manuelle,\n"
"numerotation, masquage et fonds perdus." "numerotation, masquage et fonds perdus."
) )
desc.setAlignment(Qt.AlignmentFlag.AlignCenter) desc.setAlignment(Qt.AlignmentFlag.AlignCenter)
desc.setFont(QFont("Segoe UI", 10))
desc.setStyleSheet("color: #94a3b8;")
desc.setWordWrap(True) desc.setWordWrap(True)
layout.addWidget(desc) layout.addWidget(desc)
layout.addSpacing(20)
# Separateur
sep = QLabel()
sep.setFixedHeight(1)
sep.setStyleSheet("background-color: #1e293b;")
layout.addWidget(sep)
layout.addSpacing(15) layout.addSpacing(15)
# Coordonnees # Coordonnees
contact = QLabel( contact = QLabel(
'<p style="text-align:center;">' '<p style="text-align:center; line-height: 1.6;">'
'<b>CopyDev</b><br>' '<span style="font-size:14px; font-weight:bold; color:white;">CopyDev</span><br>'
'Jules Dubois<br>' '<span style="color:#94a3b8;">Jules Dubois — Developpeur logiciel</span><br><br>'
'<a href="mailto:contact@copydev.fr">contact@copydev.fr</a><br>' '<span style="color:#94a3b8;">Email : </span>'
'<a href="https://copydev.fr">www.copydev.fr</a>' '<a href="mailto:contact@copydev.fr" style="color:#38bdf8;">contact@copydev.fr</a><br>'
'<span style="color:#94a3b8;">Web : </span>'
'<a href="https://copydev.fr" style="color:#38bdf8;">www.copydev.fr</a><br>'
'<span style="color:#94a3b8;">Tel : </span>'
'<span style="color:#e2e8f0;">06 52 07 92 35</span>'
'</p>' '</p>'
) )
contact.setAlignment(Qt.AlignmentFlag.AlignCenter) contact.setAlignment(Qt.AlignmentFlag.AlignCenter)
contact.setOpenExternalLinks(True) contact.setOpenExternalLinks(True)
layout.addWidget(contact) layout.addWidget(contact)
layout.addSpacing(5) layout.addStretch()
# Copyright # Copyright
copy_label = QLabel("© 2026 CopyDev — Tous droits reserves") copy_label = QLabel("2026 CopyDev — Tous droits reserves\nLogiciel sous licence — Reproduction interdite")
copy_label.setAlignment(Qt.AlignmentFlag.AlignCenter) copy_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
copy_label.setStyleSheet("color: #999; font-size: 11px;") copy_label.setFont(QFont("Segoe UI", 8))
copy_label.setStyleSheet("color: #334155;")
layout.addWidget(copy_label) layout.addWidget(copy_label)
# Bouton Fermer # Bouton Fermer
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
buttons.setStyleSheet("QPushButton { background: #1e293b; color: white; border: 1px solid #334155; padding: 6px 20px; border-radius: 4px; } QPushButton:hover { background: #334155; }")
buttons.rejected.connect(dlg.close) buttons.rejected.connect(dlg.close)
layout.addWidget(buttons) layout.addWidget(buttons)

88
app/splash.py Normal file
View File

@@ -0,0 +1,88 @@
"""Splash screen CopyDev au demarrage."""
import os
import sys
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QApplication
from PyQt6.QtGui import QPixmap, QFont, QColor, QPainter
from PyQt6.QtCore import Qt, QTimer
class SplashScreen(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground, False)
self.setFixedSize(500, 400)
self.setStyleSheet("background-color: #0f172a;")
layout = QVBoxLayout(self)
layout.setContentsMargins(40, 30, 40, 30)
# Logo
logo_label = QLabel()
base = sys._MEIPASS if getattr(sys, 'frozen', False) else os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
logo_path = os.path.join(base, "resources", "logo.png")
if os.path.exists(logo_path):
pixmap = QPixmap(logo_path).scaled(140, 140,
Qt.AspectRatioMode.KeepAspectRatio,
Qt.TransformationMode.SmoothTransformation)
logo_label.setPixmap(pixmap)
logo_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(logo_label)
layout.addSpacing(10)
# Nom app
title = QLabel("COPYDEV IMPOSING TOOL")
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
title.setFont(QFont("Segoe UI", 18, QFont.Weight.Bold))
title.setStyleSheet("color: white;")
layout.addWidget(title)
# Sous-titre
subtitle = QLabel("Outil professionnel d'imposition PDF")
subtitle.setAlignment(Qt.AlignmentFlag.AlignCenter)
subtitle.setFont(QFont("Segoe UI", 11))
subtitle.setStyleSheet("color: #94a3b8;")
layout.addWidget(subtitle)
layout.addSpacing(20)
# Status
self._status = QLabel("Demarrage...")
self._status.setAlignment(Qt.AlignmentFlag.AlignCenter)
self._status.setFont(QFont("Segoe UI", 9))
self._status.setStyleSheet("color: #64748b;")
layout.addWidget(self._status)
layout.addStretch()
# Coordonnees
contact = QLabel(
"CopyDev - Jules Dubois\n"
"contact@copydev.fr | www.copydev.fr"
)
contact.setAlignment(Qt.AlignmentFlag.AlignCenter)
contact.setFont(QFont("Segoe UI", 8))
contact.setStyleSheet("color: #475569;")
layout.addWidget(contact)
# Copyright
copy_label = QLabel("2026 CopyDev - Tous droits reserves")
copy_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
copy_label.setFont(QFont("Segoe UI", 7))
copy_label.setStyleSheet("color: #334155;")
layout.addWidget(copy_label)
# Centrer sur l'ecran
screen = QApplication.primaryScreen()
if screen:
geo = screen.geometry()
self.move(
(geo.width() - self.width()) // 2,
(geo.height() - self.height()) // 2
)
def set_status(self, text):
self._status.setText(text)
QApplication.processEvents()

10
main.py
View File

@@ -188,9 +188,17 @@ def main():
if os.path.exists(icon_path): if os.path.exists(icon_path):
app.setWindowIcon(QIcon(icon_path)) app.setWindowIcon(QIcon(icon_path))
# Splash screen
from app.splash import SplashScreen
splash = SplashScreen()
splash.show()
QApplication.processEvents()
splash.set_status("Verification de la licence...")
if not _check_license(): if not _check_license():
sys.exit(1) sys.exit(1)
splash.set_status("Recherche de mises a jour...")
# Verification de mise a jour silencieuse # Verification de mise a jour silencieuse
from app.updater import check_for_update, VERSION from app.updater import check_for_update, VERSION
update_available, remote_version = check_for_update() update_available, remote_version = check_for_update()
@@ -211,9 +219,11 @@ def main():
else: else:
QMessageBox.warning(None, "Mise a jour", f"Echec de la mise a jour :\n{msg}") QMessageBox.warning(None, "Mise a jour", f"Echec de la mise a jour :\n{msg}")
splash.set_status("Chargement de l'interface...")
from app.main_window import MainWindow from app.main_window import MainWindow
window = MainWindow() window = MainWindow()
window.show() window.show()
splash.close()
sys.exit(app.exec()) sys.exit(app.exec())