From 8f48fd2e3856814f50a922aeecfd9d796d19bc97 Mon Sep 17 00:00:00 2001 From: Jules Date: Sat, 21 Mar 2026 22:22:31 +0100 Subject: [PATCH] Boutons QR/Email dynamiques + mini QR sur bouton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- src/ui/screens/home_screen.py | 123 ++++++++++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 4 deletions(-) diff --git a/src/ui/screens/home_screen.py b/src/ui/screens/home_screen.py index cdf9ebc..fac0824 100644 --- a/src/ui/screens/home_screen.py +++ b/src/ui/screens/home_screen.py @@ -5,7 +5,7 @@ from PyQt6.QtWidgets import ( QStackedWidget ) from PyQt6.QtCore import Qt, QTimer, QElapsedTimer -from PyQt6.QtGui import QFont, QPixmap, QImage, QMouseEvent +from PyQt6.QtGui import QFont, QPixmap, QImage, QMouseEvent, QIcon from services.usb_watcher import UsbWatcher from ui.widgets.config_dialog import load_config, ConfigDialog @@ -106,9 +106,16 @@ class HomeScreen(QWidget): btn.setStyleSheet(blue_btn(self)) btn.setFont(scaled_font(self, Sizes.BUTTON_LARGE)) - # USB bouton vert si clé détectée + # Boutons verts si photos détectées/reçues if self._usb_photos: self.mode_buttons["USB"].setStyleSheet(green_btn(self)) + if self._qr_received_photos: + self.mode_buttons["QR Code"].setStyleSheet(green_btn(self)) + if self._email_received_photos: + self.mode_buttons["Email"].setStyleSheet(green_btn(self)) + + # Rafraîchir l'icône QR + self._set_qr_button_icon() # Tous les labels et boutons des sous-pages self._style_usb_page() @@ -170,12 +177,19 @@ class HomeScreen(QWidget): btn.sizePolicy().verticalPolicy() ) btn.clicked.connect(callback) - buttons_layout.addWidget(btn, 1) # stretch=1 pour répartir équitablement + buttons_layout.addWidget(btn, 1) self.mode_buttons[label] = btn layout.addLayout(buttons_layout) layout.addStretch() + # Compteurs de photos reçues (QR et Email) + self._qr_received_photos = [] + self._email_received_photos = [] + + # Générer le mini QR sur le bouton + QTimer.singleShot(500, self._set_qr_button_icon) + self.config_hint = QLabel("Appui long sur le titre pour accéder à la configuration") self.config_hint.setAlignment(Qt.AlignmentFlag.AlignCenter) self.config_hint.setStyleSheet("color: #bbb;") @@ -291,16 +305,29 @@ class HomeScreen(QWidget): self.qr_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.qr_status_label) + self.qr_continue_btn = QPushButton("Continuer") + self.qr_continue_btn.clicked.connect(self._import_qr) + self.qr_continue_btn.hide() + layout.addWidget(self.qr_continue_btn, alignment=Qt.AlignmentFlag.AlignCenter) + layout.addStretch() return page def _style_qr_page(self): self.qr_instruction.setFont(scaled_font(self, Sizes.HEADING)) - qr_size = scale(self, 35) # QR = 35% de la hauteur + qr_size = scale(self, 35) self.qr_image_label.setFixedSize(qr_size, qr_size) self.qr_url_label.setFont(scaled_font(self, Sizes.BODY)) self.qr_hint.setFont(scaled_font(self, Sizes.BODY)) self.qr_status_label.setFont(scaled_font(self, Sizes.BODY)) + self.qr_continue_btn.setFont(scaled_font(self, Sizes.BUTTON_LARGE, bold=True)) + self.qr_continue_btn.setMinimumHeight(scale(self, Sizes.BTN_HEIGHT)) + self.qr_continue_btn.setMinimumWidth(scale(self, 30)) + self.qr_continue_btn.setStyleSheet(green_btn(self)) + if self._qr_received_photos: + self.qr_continue_btn.show() + else: + self.qr_continue_btn.hide() # ─── Page 4 : Email ─── @@ -329,6 +356,11 @@ class HomeScreen(QWidget): self.email_status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.email_status_label) + self.email_continue_btn = QPushButton("Continuer") + self.email_continue_btn.clicked.connect(self._import_email) + self.email_continue_btn.hide() + layout.addWidget(self.email_continue_btn, alignment=Qt.AlignmentFlag.AlignCenter) + layout.addStretch() return page @@ -338,8 +370,91 @@ class HomeScreen(QWidget): self.email_address_label.setStyleSheet(highlight_box(self)) self.email_hint.setFont(scaled_font(self, Sizes.BODY)) self.email_status_label.setFont(scaled_font(self, Sizes.BODY)) + self.email_continue_btn.setFont(scaled_font(self, Sizes.BUTTON_LARGE, bold=True)) + self.email_continue_btn.setMinimumHeight(scale(self, Sizes.BTN_HEIGHT)) + self.email_continue_btn.setMinimumWidth(scale(self, 30)) + self.email_continue_btn.setStyleSheet(green_btn(self)) + if self._email_received_photos: + self.email_continue_btn.show() + else: + self.email_continue_btn.hide() self._refresh_config_labels() + # ─── Mini QR sur le bouton ─── + + def _set_qr_button_icon(self): + """Génère un mini QR code et l'affiche sur le bouton QR Code.""" + try: + import qrcode + import io + + self.config = load_config() + upload_url = self.config["upload_url"] + qr = qrcode.QRCode(version=1, box_size=4, border=1) + qr.add_data(upload_url) + qr.make(fit=True) + img = qr.make_image(fill_color="white", back_color="transparent") + + buffer = io.BytesIO() + img.save(buffer, format="PNG") + buffer.seek(0) + qimage = QImage() + qimage.loadFromData(buffer.read()) + + btn = self.mode_buttons.get("QR Code") + if btn: + qr_size = max(40, btn.height() // 3) if btn.height() > 0 else 60 + pixmap = QPixmap.fromImage(qimage).scaled( + qr_size, qr_size, + Qt.AspectRatioMode.KeepAspectRatio, + Qt.TransformationMode.SmoothTransformation + ) + btn.setIcon(QIcon(pixmap)) + from PyQt6.QtCore import QSize + btn.setIconSize(QSize(qr_size, qr_size)) + except ImportError: + pass + + # ─── Notifications photos reçues (QR / Email) ─── + + def notify_qr_photos(self, photo_paths): + """Appelé par le service upload quand des photos arrivent via QR/WiFi.""" + self._qr_received_photos.extend(photo_paths) + count = len(self._qr_received_photos) + self.mode_buttons["QR Code"].setStyleSheet(green_btn(self)) + self.qr_status_label.setText( + f"{count} photo{'s' if count > 1 else ''} reçue{'s' if count > 1 else ''}" + ) + self.qr_status_label.setStyleSheet(success_box(self)) + self.qr_continue_btn.show() + + def notify_email_photos(self, photo_paths): + """Appelé par le service email quand des photos arrivent.""" + self._email_received_photos.extend(photo_paths) + count = len(self._email_received_photos) + self.mode_buttons["Email"].setStyleSheet(green_btn(self)) + self.email_status_label.setText( + f"{count} photo{'s' if count > 1 else ''} reçue{'s' if count > 1 else ''}" + ) + self.email_status_label.setStyleSheet(success_box(self)) + self.email_continue_btn.show() + + def _import_qr(self): + if self._qr_received_photos: + self.main_window.import_screen.set_photos(self._qr_received_photos) + self.main_window.show_import() + + def _import_email(self): + if self._email_received_photos: + self.main_window.import_screen.set_photos(self._email_received_photos) + self.main_window.show_import() + + def get_qr_photos(self): + return list(self._qr_received_photos) + + def get_email_photos(self): + return list(self._email_received_photos) + # ─── Navigation ─── def _show_modes(self):