Bouton Retour visible + menu config admin

- Bouton "< Retour" gros en haut à gauche sur chaque page d'instructions
- Appui long (5 sec) sur le titre "Photostation" = ouvre config admin
- Config : nom WiFi, mot de passe, URL QR, adresse email, imprimante CUPS
- Config sauvegardée dans config/settings.json
- Labels WiFi/QR/Email mis à jour dynamiquement depuis la config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-21 19:46:39 +01:00
parent f5161d7a31
commit 4f6d55bc43
2 changed files with 282 additions and 105 deletions

View File

@@ -2,16 +2,13 @@
from PyQt6.QtWidgets import ( from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel,
QStackedWidget, QSizePolicy QStackedWidget
) )
from PyQt6.QtCore import Qt, QTimer from PyQt6.QtCore import Qt, QTimer, QElapsedTimer
from PyQt6.QtGui import QFont, QPixmap, QImage from PyQt6.QtGui import QFont, QPixmap, QImage, QMouseEvent
from services.usb_watcher import UsbWatcher from services.usb_watcher import UsbWatcher
from ui.widgets.config_dialog import load_config, ConfigDialog
WIFI_AP_NAME = "Photostation"
WIFI_AP_PASSWORD = "photo1234"
EMAIL_ADDRESS = "photo@photostation.local"
BTN_STYLE = """ BTN_STYLE = """
QPushButton {{ QPushButton {{
@@ -31,19 +28,13 @@ BACK_BTN_STYLE = """
QPushButton { QPushButton {
background-color: #757575; background-color: #757575;
color: white; color: white;
border-radius: 10px; border-radius: 12px;
padding: 10px 30px; padding: 12px 30px;
font-size: 16px;
} }
QPushButton:pressed { background-color: #616161; } QPushButton:pressed { background-color: #616161; }
""" """
INFO_STYLE = """
QLabel {
color: #333;
padding: 10px;
}
"""
HIGHLIGHT_STYLE = """ HIGHLIGHT_STYLE = """
QLabel { QLabel {
background-color: #E3F2FD; background-color: #E3F2FD;
@@ -75,6 +66,36 @@ SUCCESS_STYLE = """
} }
""" """
INFO_STYLE = """
QLabel {
color: #333;
padding: 10px;
}
"""
class LongPressLabel(QLabel):
"""QLabel qui détecte l'appui long (5 sec) pour ouvrir la config."""
def __init__(self, text, callback, parent=None):
super().__init__(text, parent)
self._callback = callback
self._press_timer = QElapsedTimer()
self._long_press_timer = QTimer(self)
self._long_press_timer.setSingleShot(True)
self._long_press_timer.timeout.connect(self._on_long_press)
def mousePressEvent(self, event: QMouseEvent):
self._long_press_timer.start(5000)
super().mousePressEvent(event)
def mouseReleaseEvent(self, event: QMouseEvent):
self._long_press_timer.stop()
super().mouseReleaseEvent(event)
def _on_long_press(self):
self._callback()
class HomeScreen(QWidget): class HomeScreen(QWidget):
def __init__(self, main_window): def __init__(self, main_window):
@@ -82,34 +103,46 @@ class HomeScreen(QWidget):
self.main_window = main_window self.main_window = main_window
self._usb_photos = [] self._usb_photos = []
self._usb_mount = None self._usb_mount = None
self.config = load_config()
self._setup_ui() self._setup_ui()
self._setup_usb_watcher() self._setup_usb_watcher()
def _setup_ui(self): def _setup_ui(self):
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.setContentsMargins(20, 20, 20, 20) layout.setContentsMargins(20, 15, 20, 15)
layout.setSpacing(20) layout.setSpacing(10)
# Titre (toujours visible) # Titre (appui long 5s = config)
title = QLabel("Photostation") self.title = LongPressLabel("Photostation", self._open_config)
title.setFont(QFont("", 42, QFont.Weight.Bold)) self.title.setFont(QFont("", 42, QFont.Weight.Bold))
title.setAlignment(Qt.AlignmentFlag.AlignCenter) self.title.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title) layout.addWidget(self.title)
# Zone switchable : choix des modes OU instructions d'un mode # Zone switchable
self.stack = QStackedWidget() self.stack = QStackedWidget()
layout.addWidget(self.stack, 1) layout.addWidget(self.stack, 1)
# Page 0 : Choix des modes # Pages
self.stack.addWidget(self._build_mode_selection()) self.stack.addWidget(self._build_mode_selection()) # 0
# Page 1 : Instructions USB self.stack.addWidget(self._build_usb_page()) # 1
self.stack.addWidget(self._build_usb_instructions()) self.stack.addWidget(self._build_wifi_page()) # 2
# Page 2 : Instructions WiFi self.stack.addWidget(self._build_qr_page()) # 3
self.stack.addWidget(self._build_wifi_instructions()) self.stack.addWidget(self._build_email_page()) # 4
# Page 3 : Instructions QR Code
self.stack.addWidget(self._build_qr_instructions()) def _make_back_button(self):
# Page 4 : Instructions Email btn = QPushButton("< Retour")
self.stack.addWidget(self._build_email_instructions()) btn.setFont(QFont("", 16, QFont.Weight.Bold))
btn.setMinimumSize(150, 55)
btn.setStyleSheet(BACK_BTN_STYLE)
btn.clicked.connect(self._show_modes)
return btn
def _make_page_header(self):
"""Header commun : gros bouton Retour en haut à gauche."""
header = QHBoxLayout()
header.addWidget(self._make_back_button())
header.addStretch()
return header
# ─── Page 0 : Sélection des modes ─── # ─── Page 0 : Sélection des modes ───
@@ -129,7 +162,7 @@ class HomeScreen(QWidget):
modes = [ modes = [
("USB", "Clé USB", self._show_usb), ("USB", "Clé USB", self._show_usb),
("WiFi", "Depuis téléphone", self._show_wifi), ("WiFi", "Depuis\ntéléphone", self._show_wifi),
("QR Code", "Scanner pour\nenvoyer", self._show_qr), ("QR Code", "Scanner pour\nenvoyer", self._show_qr),
("Email", "Recevoir par\nmail", self._show_email), ("Email", "Recevoir par\nmail", self._show_email),
] ]
@@ -145,31 +178,39 @@ class HomeScreen(QWidget):
self.mode_buttons[label] = btn self.mode_buttons[label] = btn
layout.addLayout(buttons_layout) layout.addLayout(buttons_layout)
# Hint config
hint = QLabel("Appui long sur le titre pour accéder à la configuration")
hint.setFont(QFont("", 10))
hint.setAlignment(Qt.AlignmentFlag.AlignCenter)
hint.setStyleSheet("color: #bbb;")
layout.addWidget(hint)
return page return page
# ─── Page 1 : USB ─── # ─── Page 1 : USB ───
def _build_usb_instructions(self): def _build_usb_page(self):
page = QWidget() page = QWidget()
layout = QVBoxLayout(page) layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.setSpacing(20)
layout.setSpacing(25)
layout.addLayout(self._make_page_header())
# Instruction principale
instruction = QLabel("Insérez votre clé USB dans le port\nde la borne") instruction = QLabel("Insérez votre clé USB dans le port\nde la borne")
instruction.setFont(QFont("", 24)) instruction.setFont(QFont("", 24))
instruction.setAlignment(Qt.AlignmentFlag.AlignCenter) instruction.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(instruction) layout.addWidget(instruction)
# Zone de status (change dynamiquement) layout.addStretch()
self.usb_status_label = QLabel("En attente de la clé USB...")
self.usb_status_label = QLabel("Clé USB non détectée\nInsérez votre clé USB puis patientez quelques secondes")
self.usb_status_label.setFont(QFont("", 18)) self.usb_status_label.setFont(QFont("", 18))
self.usb_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.usb_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.usb_status_label.setMinimumHeight(70) self.usb_status_label.setMinimumHeight(80)
self.usb_status_label.setStyleSheet(HIGHLIGHT_STYLE) self.usb_status_label.setStyleSheet(ERROR_STYLE)
layout.addWidget(self.usb_status_label) layout.addWidget(self.usb_status_label)
# Bouton continuer (masqué tant que pas de clé)
self.usb_continue_btn = QPushButton("Continuer") self.usb_continue_btn = QPushButton("Continuer")
self.usb_continue_btn.setFont(QFont("", 18, QFont.Weight.Bold)) self.usb_continue_btn.setFont(QFont("", 18, QFont.Weight.Bold))
self.usb_continue_btn.setMinimumSize(250, 60) self.usb_continue_btn.setMinimumSize(250, 60)
@@ -178,46 +219,36 @@ class HomeScreen(QWidget):
self.usb_continue_btn.hide() self.usb_continue_btn.hide()
layout.addWidget(self.usb_continue_btn, alignment=Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.usb_continue_btn, alignment=Qt.AlignmentFlag.AlignCenter)
# Bouton retour layout.addStretch()
back = QPushButton("Retour")
back.setFont(QFont("", 14))
back.setStyleSheet(BACK_BTN_STYLE)
back.clicked.connect(self._show_modes)
layout.addWidget(back, alignment=Qt.AlignmentFlag.AlignCenter)
return page return page
# ─── Page 2 : WiFi ─── # ─── Page 2 : WiFi ───
def _build_wifi_instructions(self): def _build_wifi_page(self):
page = QWidget() page = QWidget()
layout = QVBoxLayout(page) layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.setSpacing(20)
layout.setSpacing(25)
layout.addLayout(self._make_page_header())
instruction = QLabel("Connectez-vous au réseau WiFi\nde la borne depuis votre téléphone") instruction = QLabel("Connectez-vous au réseau WiFi\nde la borne depuis votre téléphone")
instruction.setFont(QFont("", 24)) instruction.setFont(QFont("", 24))
instruction.setAlignment(Qt.AlignmentFlag.AlignCenter) instruction.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(instruction) layout.addWidget(instruction)
# Infos réseau layout.addStretch()
info_box = QWidget()
info_layout = QVBoxLayout(info_box)
info_layout.setSpacing(10)
net_name = QLabel(f"Nom du réseau : {WIFI_AP_NAME}") self.wifi_name_label = QLabel(f"Nom du réseau : {self.config['wifi_ap_name']}")
net_name.setFont(QFont("", 22, QFont.Weight.Bold)) self.wifi_name_label.setFont(QFont("", 22, QFont.Weight.Bold))
net_name.setAlignment(Qt.AlignmentFlag.AlignCenter) self.wifi_name_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
net_name.setStyleSheet(HIGHLIGHT_STYLE) self.wifi_name_label.setStyleSheet(HIGHLIGHT_STYLE)
info_layout.addWidget(net_name) layout.addWidget(self.wifi_name_label)
net_pass = QLabel(f"Mot de passe : {WIFI_AP_PASSWORD}") self.wifi_pass_label = QLabel(f"Mot de passe : {self.config['wifi_ap_password']}")
net_pass.setFont(QFont("", 22, QFont.Weight.Bold)) self.wifi_pass_label.setFont(QFont("", 22, QFont.Weight.Bold))
net_pass.setAlignment(Qt.AlignmentFlag.AlignCenter) self.wifi_pass_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
net_pass.setStyleSheet(HIGHLIGHT_STYLE) self.wifi_pass_label.setStyleSheet(HIGHLIGHT_STYLE)
info_layout.addWidget(net_pass) layout.addWidget(self.wifi_pass_label)
layout.addWidget(info_box)
step2 = QLabel("Une fois connecté, une page s'ouvrira\nautomatiquement pour envoyer vos photos") step2 = QLabel("Une fois connecté, une page s'ouvrira\nautomatiquement pour envoyer vos photos")
step2.setFont(QFont("", 16)) step2.setFont(QFont("", 16))
@@ -225,42 +256,35 @@ class HomeScreen(QWidget):
step2.setStyleSheet("color: #666;") step2.setStyleSheet("color: #666;")
layout.addWidget(step2) layout.addWidget(step2)
# Status connexions
self.wifi_status_label = QLabel("En attente de connexion...") self.wifi_status_label = QLabel("En attente de connexion...")
self.wifi_status_label.setFont(QFont("", 16)) self.wifi_status_label.setFont(QFont("", 16))
self.wifi_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.wifi_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.wifi_status_label.setStyleSheet(INFO_STYLE) self.wifi_status_label.setStyleSheet(INFO_STYLE)
layout.addWidget(self.wifi_status_label) layout.addWidget(self.wifi_status_label)
back = QPushButton("Retour") layout.addStretch()
back.setFont(QFont("", 14))
back.setStyleSheet(BACK_BTN_STYLE)
back.clicked.connect(self._show_modes)
layout.addWidget(back, alignment=Qt.AlignmentFlag.AlignCenter)
return page return page
# ─── Page 3 : QR Code ─── # ─── Page 3 : QR Code ───
def _build_qr_instructions(self): def _build_qr_page(self):
page = QWidget() page = QWidget()
layout = QVBoxLayout(page) layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.setSpacing(15)
layout.setSpacing(20)
layout.addLayout(self._make_page_header())
instruction = QLabel("Scannez ce QR code avec votre téléphone\npour envoyer vos photos") instruction = QLabel("Scannez ce QR code avec votre téléphone\npour envoyer vos photos")
instruction.setFont(QFont("", 24)) instruction.setFont(QFont("", 24))
instruction.setAlignment(Qt.AlignmentFlag.AlignCenter) instruction.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(instruction) layout.addWidget(instruction)
# QR Code affiché
self.qr_image_label = QLabel() self.qr_image_label = QLabel()
self.qr_image_label.setFixedSize(250, 250) self.qr_image_label.setFixedSize(250, 250)
self.qr_image_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.qr_image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.qr_image_label.setStyleSheet("background-color: white; border: 2px solid #ccc; border-radius: 10px;") self.qr_image_label.setStyleSheet("background-color: white; border: 2px solid #ccc; border-radius: 10px;")
layout.addWidget(self.qr_image_label, alignment=Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.qr_image_label, alignment=Qt.AlignmentFlag.AlignCenter)
# URL affichée en texte aussi
self.qr_url_label = QLabel("") self.qr_url_label = QLabel("")
self.qr_url_label.setFont(QFont("", 14)) self.qr_url_label.setFont(QFont("", 14))
self.qr_url_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.qr_url_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
@@ -273,40 +297,35 @@ class HomeScreen(QWidget):
hint.setStyleSheet("color: #666;") hint.setStyleSheet("color: #666;")
layout.addWidget(hint) layout.addWidget(hint)
# Status réception
self.qr_status_label = QLabel("En attente de photos...") self.qr_status_label = QLabel("En attente de photos...")
self.qr_status_label.setFont(QFont("", 16)) self.qr_status_label.setFont(QFont("", 16))
self.qr_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.qr_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.qr_status_label.setStyleSheet(INFO_STYLE) self.qr_status_label.setStyleSheet(INFO_STYLE)
layout.addWidget(self.qr_status_label) layout.addWidget(self.qr_status_label)
back = QPushButton("Retour") layout.addStretch()
back.setFont(QFont("", 14))
back.setStyleSheet(BACK_BTN_STYLE)
back.clicked.connect(self._show_modes)
layout.addWidget(back, alignment=Qt.AlignmentFlag.AlignCenter)
return page return page
# ─── Page 4 : Email ─── # ─── Page 4 : Email ───
def _build_email_instructions(self): def _build_email_page(self):
page = QWidget() page = QWidget()
layout = QVBoxLayout(page) layout = QVBoxLayout(page)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.setSpacing(20)
layout.setSpacing(25)
layout.addLayout(self._make_page_header())
instruction = QLabel("Envoyez vos photos par email\nà l'adresse suivante :") instruction = QLabel("Envoyez vos photos par email\nà l'adresse suivante :")
instruction.setFont(QFont("", 24)) instruction.setFont(QFont("", 24))
instruction.setAlignment(Qt.AlignmentFlag.AlignCenter) instruction.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(instruction) layout.addWidget(instruction)
# Adresse email mise en évidence layout.addStretch()
self.email_address_label = QLabel(EMAIL_ADDRESS)
self.email_address_label = QLabel(self.config["email_address"])
self.email_address_label.setFont(QFont("", 28, QFont.Weight.Bold)) self.email_address_label.setFont(QFont("", 28, QFont.Weight.Bold))
self.email_address_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.email_address_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.email_address_label.setStyleSheet(HIGHLIGHT_STYLE) self.email_address_label.setStyleSheet(HIGHLIGHT_STYLE)
self.email_address_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
layout.addWidget(self.email_address_label) layout.addWidget(self.email_address_label)
hint = QLabel("Joignez vos photos en pièce jointe\net envoyez depuis votre téléphone") hint = QLabel("Joignez vos photos en pièce jointe\net envoyez depuis votre téléphone")
@@ -315,22 +334,16 @@ class HomeScreen(QWidget):
hint.setStyleSheet("color: #666;") hint.setStyleSheet("color: #666;")
layout.addWidget(hint) layout.addWidget(hint)
# Status réception
self.email_status_label = QLabel("En attente de réception...") self.email_status_label = QLabel("En attente de réception...")
self.email_status_label.setFont(QFont("", 16)) self.email_status_label.setFont(QFont("", 16))
self.email_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.email_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.email_status_label.setStyleSheet(INFO_STYLE) self.email_status_label.setStyleSheet(INFO_STYLE)
layout.addWidget(self.email_status_label) layout.addWidget(self.email_status_label)
back = QPushButton("Retour") layout.addStretch()
back.setFont(QFont("", 14))
back.setStyleSheet(BACK_BTN_STYLE)
back.clicked.connect(self._show_modes)
layout.addWidget(back, alignment=Qt.AlignmentFlag.AlignCenter)
return page return page
# ─── Navigation entre pages ─── # ─── Navigation ───
def _show_modes(self): def _show_modes(self):
self.stack.setCurrentIndex(0) self.stack.setCurrentIndex(0)
@@ -340,15 +353,32 @@ class HomeScreen(QWidget):
self.stack.setCurrentIndex(1) self.stack.setCurrentIndex(1)
def _show_wifi(self): def _show_wifi(self):
self._refresh_config_labels()
self.stack.setCurrentIndex(2) self.stack.setCurrentIndex(2)
def _show_qr(self): def _show_qr(self):
self._refresh_config_labels()
self._generate_qr() self._generate_qr()
self.stack.setCurrentIndex(3) self.stack.setCurrentIndex(3)
def _show_email(self): def _show_email(self):
self._refresh_config_labels()
self.stack.setCurrentIndex(4) self.stack.setCurrentIndex(4)
# ─── Config ───
def _open_config(self):
if ConfigDialog.open_config(self):
self.config = load_config()
self._refresh_config_labels()
def _refresh_config_labels(self):
"""Met à jour les labels avec la config actuelle."""
self.config = load_config()
self.wifi_name_label.setText(f"Nom du réseau : {self.config['wifi_ap_name']}")
self.wifi_pass_label.setText(f"Mot de passe : {self.config['wifi_ap_password']}")
self.email_address_label.setText(self.config["email_address"])
# ─── USB ─── # ─── USB ───
def _setup_usb_watcher(self): def _setup_usb_watcher(self):
@@ -395,13 +425,12 @@ class HomeScreen(QWidget):
import qrcode import qrcode
import io import io
upload_url = f"http://192.168.4.1/upload" upload_url = self.config["upload_url"]
qr = qrcode.QRCode(version=1, box_size=8, border=2) qr = qrcode.QRCode(version=1, box_size=8, border=2)
qr.add_data(upload_url) qr.add_data(upload_url)
qr.make(fit=True) qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white") img = qr.make_image(fill_color="black", back_color="white")
# PIL Image -> QPixmap
buffer = io.BytesIO() buffer = io.BytesIO()
img.save(buffer, format="PNG") img.save(buffer, format="PNG")
buffer.seek(0) buffer.seek(0)

View File

@@ -0,0 +1,148 @@
"""Dialogue de configuration admin — accessible par appui long sur le titre."""
import json
import os
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout,
QLineEdit, QPushButton, QLabel, QComboBox, QGroupBox
)
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QFont
CONFIG_PATH = os.path.join(
os.path.dirname(__file__), "..", "..", "..", "config", "settings.json"
)
DEFAULT_CONFIG = {
"wifi_ap_name": "Photostation",
"wifi_ap_password": "photo1234",
"email_address": "photo@photostation.local",
"upload_url": "http://192.168.4.1/upload",
"printer_name": "",
"print_format": "10x15 cm",
"kiosk_mode": False,
}
def load_config():
try:
with open(CONFIG_PATH, "r") as f:
saved = json.load(f)
config = dict(DEFAULT_CONFIG)
config.update(saved)
return config
except (FileNotFoundError, json.JSONDecodeError):
return dict(DEFAULT_CONFIG)
def save_config(config):
os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True)
with open(CONFIG_PATH, "w") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
class ConfigDialog(QDialog):
"""Panneau de configuration admin."""
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Configuration — Admin")
self.setMinimumSize(500, 450)
self.config = load_config()
self._setup_ui()
def _setup_ui(self):
layout = QVBoxLayout(self)
layout.setSpacing(15)
# Titre
title = QLabel("Configuration Photostation")
title.setFont(QFont("", 20, QFont.Weight.Bold))
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title)
# WiFi
wifi_group = QGroupBox("WiFi (Hotspot)")
wifi_form = QFormLayout(wifi_group)
self.wifi_name_input = QLineEdit(self.config["wifi_ap_name"])
self.wifi_name_input.setFont(QFont("", 14))
self.wifi_name_input.setMinimumHeight(40)
wifi_form.addRow("Nom du réseau :", self.wifi_name_input)
self.wifi_pass_input = QLineEdit(self.config["wifi_ap_password"])
self.wifi_pass_input.setFont(QFont("", 14))
self.wifi_pass_input.setMinimumHeight(40)
wifi_form.addRow("Mot de passe :", self.wifi_pass_input)
layout.addWidget(wifi_group)
# QR Code
qr_group = QGroupBox("QR Code")
qr_form = QFormLayout(qr_group)
self.upload_url_input = QLineEdit(self.config["upload_url"])
self.upload_url_input.setFont(QFont("", 14))
self.upload_url_input.setMinimumHeight(40)
qr_form.addRow("URL d'upload :", self.upload_url_input)
layout.addWidget(qr_group)
# Email
email_group = QGroupBox("Email")
email_form = QFormLayout(email_group)
self.email_input = QLineEdit(self.config["email_address"])
self.email_input.setFont(QFont("", 14))
self.email_input.setMinimumHeight(40)
email_form.addRow("Adresse email :", self.email_input)
layout.addWidget(email_group)
# Imprimante
printer_group = QGroupBox("Impression")
printer_form = QFormLayout(printer_group)
self.printer_input = QLineEdit(self.config["printer_name"])
self.printer_input.setFont(QFont("", 14))
self.printer_input.setMinimumHeight(40)
self.printer_input.setPlaceholderText("Nom CUPS (vide = par défaut)")
printer_form.addRow("Imprimante :", self.printer_input)
self.format_combo = QComboBox()
self.format_combo.setFont(QFont("", 14))
self.format_combo.setMinimumHeight(40)
self.format_combo.addItems(["10x15 cm", "13x18 cm", "15x20 cm"])
self.format_combo.setCurrentText(self.config["print_format"])
printer_form.addRow("Format par défaut :", self.format_combo)
layout.addWidget(printer_group)
# Boutons
buttons = QHBoxLayout()
cancel_btn = QPushButton("Annuler")
cancel_btn.setFont(QFont("", 14))
cancel_btn.setMinimumHeight(50)
cancel_btn.setStyleSheet("""
QPushButton { background-color: #757575; color: white; border-radius: 10px; padding: 10px 30px; }
QPushButton:pressed { background-color: #616161; }
""")
cancel_btn.clicked.connect(self.reject)
buttons.addWidget(cancel_btn)
save_btn = QPushButton("Enregistrer")
save_btn.setFont(QFont("", 14, QFont.Weight.Bold))
save_btn.setMinimumHeight(50)
save_btn.setStyleSheet("""
QPushButton { background-color: #4CAF50; color: white; border-radius: 10px; padding: 10px 30px; }
QPushButton:pressed { background-color: #388E3C; }
""")
save_btn.clicked.connect(self._save)
buttons.addWidget(save_btn)
layout.addLayout(buttons)
def _save(self):
self.config["wifi_ap_name"] = self.wifi_name_input.text()
self.config["wifi_ap_password"] = self.wifi_pass_input.text()
self.config["upload_url"] = self.upload_url_input.text()
self.config["email_address"] = self.email_input.text()
self.config["printer_name"] = self.printer_input.text()
self.config["print_format"] = self.format_combo.currentText()
save_config(self.config)
self.accept()
@staticmethod
def open_config(parent=None):
dialog = ConfigDialog(parent)
return dialog.exec() == QDialog.DialogCode.Accepted