Code source de presenters.main_presenter

"""
Presenter principal de l'application
Coordonne l'initialisation et la communication entre les composants
"""
import sys
from PySide6.QtWidgets import QApplication, QMessageBox

from infrastructure.api.pokeapi_service import PokeAPIService
from core.type_calculator import TypeCalculator
from infrastructure.ocr.tesseract_ocr import TesseractOCR, test_ocr_setup
from services.analysis_service import AnalysisService
from services.capture_service import CaptureService

from ui.main_window import MainWindow
from presenters.capture_presenter import CapturePresenter
from presenters.search_presenter import SearchPresenter

[docs] class MainPresenter: """ Presenter principal """
[docs] def __init__(self): # Initialise l'application Qt self.app = QApplication(sys.argv) self.app.setApplicationName("Pokémon Analyzer") self.app.setOrganizationName("PokemonOCR") # Workaround pour le bug d'affichage des QSpinBox sur Windows 11 avec Qt 6.7+ # Force le style "windowsvista" pour retrouver les boutons verticaux natifs if sys.platform == "win32": self.app.setStyle("windowsvista") # Initialise les services self._init_services() # Initialise la vue principale self.view = MainWindow() # Initialise les presenters enfants self._init_presenters() # Charge les styles self._load_styles()
def _init_services(self): """Initialise tous les services""" try: # Core & Infrastructure self.db = PokeAPIService() self.calc = TypeCalculator() # OCR if test_ocr_setup(): # Récupère les noms pour l'OCR pokemon_names = self.db.get_all_pokemon_names() self.ocr = TesseractOCR(pokemon_names) self.ocr_status = "OCR disponible" else: self.ocr = None self.ocr_status = "OCR non disponible" # Services applicatifs self.analysis_service = AnalysisService(self.calc) self.capture_service = CaptureService(self.ocr) except Exception as e: print(f"Erreur d'initialisation: {e}") sys.exit(1) def _init_presenters(self): """Initialise les presenters pour chaque onglet""" # Capture Tab self.capture_presenter = CapturePresenter( self.view.live_capture_tab, self.capture_service, self.analysis_service, self.db, self.calc ) # Search Tab self.search_presenter = SearchPresenter( self.view.search_tab, self.db, self.calc ) # Connecte les signaux inter-onglets self._connect_cross_tab_signals() # Met à jour le statut initial pokemon_count = len(self.db._names_db) self.view.show_status_message( f"Modules initialisés - {pokemon_count} noms disponibles - {self.ocr_status}" ) def _connect_cross_tab_signals(self): """Connecte les signaux entre les onglets (via les presenters ou directement)""" # Quand un Pokémon est sélectionné dans la recherche, on l'affiche dans l'onglet capture self.view.search_tab.pokemon_selected.connect(self._on_pokemon_selected_from_search) # Connecte le changement de langue self.view.lang_combo.currentTextChanged.connect(self._on_language_changed) def _on_language_changed(self, text): """Gère le changement de langue""" lang_map = { "Français": "fr", "English": "en", "Deutsch": "de", "Español": "es", "Italiano": "it", "日本語": "jp" } code = lang_map.get(text, "fr") # Met à jour la langue dans le système de traduction from core.translations import set_language set_language(code) # Met à jour la langue dans l'API self.db.set_language(code) # Met à jour les noms de Pokémon dans l'OCR pour la nouvelle langue if self.ocr: pokemon_names = self.db.get_all_pokemon_names() self.ocr.update_pokemon_names(pokemon_names) # Rafraîchit l'interface self.view.update_translations() # Rafraîchit les résultats de recherche si nécessaire if self.search_presenter: self.search_presenter.refresh_results() # Rafraîchit l'affichage du/des Pokémon actuellement visible(s) if self.capture_presenter: self.capture_presenter.refresh_current_display() # Met à jour le statut from core.translations import t self.view.show_status_message(t('status_language_changed') + f": {text}") def _on_pokemon_selected_from_search(self, pokemon_name): """Gère la sélection depuis la recherche""" # Bascule vers l'onglet capture self.view.switch_to_tab(0) # 0 = Capture Tab # Simule une détection pour l'afficher # On utilise le presenter de capture pour ça # Note: On triche un peu en créant un résultat fictif pokemon_data = self.db.get_pokemon_by_name(pokemon_name) if pokemon_data: # Appelle directement la méthode de gestion du presenter capture self.capture_presenter.handle_single_pokemon_detection( pokemon_name, 1.0, # Confiance 100% {'image': None} # Pas d'image ) def _load_styles(self): """Charge les styles QSS""" try: import os style_path = os.path.join(os.path.dirname(__file__), '../assets/styles.qss') if os.path.exists(style_path): with open(style_path, 'r') as f: self.view.setStyleSheet(f.read()) except Exception as e: print(f"Erreur chargement styles: {e}")
[docs] def run(self): """Lance l'application""" self.view.show() sys.exit(self.app.exec_())