Thread Flask met les photos dans une queue.Queue().
QTimer(500ms) dans le thread principal Qt poll la queue
et appelle le callback. Approche fiable et simple.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pyqtSignal.emit() depuis un thread Python standard ne fonctionne pas.
Utilise QTimer.singleShot(0, callback) qui est thread-safe et
exécute le callback dans le thread principal Qt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Les signaux émis depuis les threads Flask/IMAP ne déclenchaient pas
le slot dans le thread principal. Forcé QueuedConnection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_apply_responsive_styles modifiait les widgets, déclenchant resizeEvent
en boucle. Ajout d'un flag _styling pour bloquer la récursion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- box_size=20 pour générer en haute résolution
- FastTransformation (pas de lissage = pixels nets)
- QR prend 55% de la hauteur du bouton
- Fond bleu (#2196F3), QR blanc pour contraste
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton QR Code affiche un mini QR code en icône
- Boutons QR et Email passent au vert quand photos reçues
- Bouton Continuer apparaît sur pages QR/Email quand photos dispo
- API notify_qr_photos() / notify_email_photos() pour les services
- Méthodes _import_qr / _import_email pour naviguer vers la galerie
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- La photo en cours est dupliquée dans toutes les zones du template
- Crop to fill : l'image remplit chaque zone au maximum (pas de bords)
- Fonctionne avec l'image éditée (filtres, etc.) pas juste l'originale
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FramelessWindowHint + setGeometry(screen) pour fonctionner
sans window manager (Xvfb, RPi kiosk).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remplacé GroupBox/FormLayout par QGridLayout compact
- Ajout QScrollArea pour les petits écrans
- Dialog prend la taille du parent
- Titres de section colorés, inputs stylés
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Nouveau module ui/style.py : scale(), scaled_font(), styles dynamiques
- Toutes les tailles (polices, boutons, marges, padding, border-radius)
calculées en % de la hauteur de la fenêtre
- S'adapte automatiquement à 800x480, 1024x768, 1920x1080, etc.
- Recalcul au resize de la fenêtre
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
- USB : message "insérez votre clé", erreur si non détectée, bouton vert + continuer
- WiFi : affiche nom AP + mot de passe
- QR Code : génère et affiche le QR code (URL upload)
- Email : affiche l'adresse email provisoire
- Navigation : boutons mode → page instructions → retour
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>