From ce1b864b17ebecdf098cdff95375a54a949b6959 Mon Sep 17 00:00:00 2001 From: bartool Date: Sun, 12 Oct 2025 19:02:53 +0200 Subject: [PATCH] refactor: streamline MainController initialization and signal connections --- controllers/main_controller.py | 269 ++++++++++++++++----------------- 1 file changed, 131 insertions(+), 138 deletions(-) diff --git a/controllers/main_controller.py b/controllers/main_controller.py index 3853eb4..77b99ba 100644 --- a/controllers/main_controller.py +++ b/controllers/main_controller.py @@ -1,161 +1,154 @@ -from PySide6.QtWidgets import QPushButton from pathlib import Path +from PySide6.QtCore import Slot +from PySide6.QtGui import QPixmap +from PySide6.QtWidgets import QPushButton + from core.database import DatabaseManager from core.media import MediaRepository +from core.camera.camera_manager import CameraManager from ui.widgets.color_list_widget import ColorListWidget from ui.widgets.thumbnail_list_widget import ThumbnailListWidget from ui.widgets.split_view_widget import SplitView, CameraPlaceholder -# from .camera_controller import CameraController -from core.camera.camera_controller import CameraController -from core.camera.camera_manager import CameraManager -from core.camera.gphoto_camera import GPhotoCamera -from core.camera.camera_controller import CameraController - class MainController: - def __init__(self, view): - self.db = DatabaseManager() - self.db.connect() - self.media_repo = MediaRepository(self.db) - self.media_repo.sync_media() + def __init__(self, view): + self.view = view + self.db = DatabaseManager() + self.media_repo = MediaRepository(self.db) + self.camera_manager = CameraManager() - # camera = GPhotoCamera() - # self.manager = CameraController(camera) - manager = CameraManager() - # manager.detect_gphoto() - # manager.detect_opencv() - manager.detect_camera() + # --- UI Widgets --- + self.color_list: ColorListWidget = view.color_list_widget + self.thumbnail_list: ThumbnailListWidget = view.thumbnail_widget + self.split_view: SplitView = view.preview_widget + self.welcome_view: CameraPlaceholder = self.split_view.widget_start + self.photo_button: QPushButton = view.photo_button + self.record_button: QPushButton = view.record_button - # self.camera_controller = CameraController() + self._connect_signals() - self.view = view - self.color_list: ColorListWidget = view.color_list_widget - self.thumbnail_list: ThumbnailListWidget = view.thumbnail_widget - self.split_view: SplitView = view.preview_widget - self.welcome_view: CameraPlaceholder = self.split_view.widget_start + self.db.connect() + self.media_repo.sync_media() + self.camera_manager.detect_cameras() - self.photo_button: QPushButton = view.photo_button - self.photo_button.clicked.connect(self.take_photo) + def _connect_signals(self): + """Connects all signals to slots.""" + # Database and media signals + self.color_list.colorSelected.connect(self.on_color_selected) + self.color_list.editColor.connect(self.on_edit_color) + self.thumbnail_list.selectedThumbnail.connect(self.on_thumbnail_selected) - self.record_button: QPushButton = view.record_button - # self.record_button.clicked.connect(self.fun_test) + # Camera signals + self.camera_manager.cameras_detected.connect(self.on_cameras_detected) + self.camera_manager.frame_ready.connect(self.on_frame_ready) + self.camera_manager.error_occurred.connect(self.on_camera_error) + self.camera_manager.camera_started.connect(self.on_camera_started) + self.camera_manager.camera_stopped.connect(self.on_camera_stopped) - self.color_list.colorSelected.connect(self.on_color_selected) - self.color_list.editColor.connect(self.on_edit_color) - self.thumbnail_list.selectedThumbnail.connect(self.on_thumbnail_selected) + # UI control signals + self.photo_button.clicked.connect(self.take_photo) + # self.record_button.clicked.connect(self.toggle_record) # Placeholder + self.welcome_view.camera_start_btn.clicked.connect(self.start_liveview) + # You will need a way to select a camera, e.g., a combobox. + # self.view.camera_combobox.currentIndexChanged.connect(self.on_camera_selected_in_ui) - # self.camera_controller.errorOccurred.connect(self.split_view.widget_start.set_info_text) - # self.manager.error_occurred.connect(self.split_view.widget_start.set_info_text) - # self.camera_controller.frameReady.connect(self.split_view.set_live_image) - # self.manager.frame_ready.connect(self.split_view.set_live_image) - # self.split_view.widget_start.camera_start_btn.clicked.connect(self.camera_controller.start) - self.split_view.widget_start.camera_start_btn.clicked.connect(self.start_liveview) + def load_colors(self) -> None: + """Loads colors from the database and populates the list.""" + colors = self.db.get_all_colors() + self.color_list.set_colors(colors) - self.welcome_view.set_button_text("tada") - self.welcome_view.set_error_text("errorsy") + def shutdown(self): + """Cleans up resources before application exit.""" + self.camera_manager.shutdown() + self.db.disconnect() + + # --- Slots for Database/Media --- + + @Slot(str) + def on_color_selected(self, color_name: str): + color_id = self.db.get_color_id(color_name) + if color_id is not None: + media_items = self.db.get_media_for_color(color_id) + self.thumbnail_list.list_widget.clear() + for media in media_items: + if media['file_type'] == 'photo': + file_name = Path(media['media_path']).name + self.thumbnail_list.add_thumbnail(media['media_path'], file_name, media['id']) + + @Slot(str) + def on_edit_color(self, color_name: str): + print(f"Edycja koloru: {color_name}") # Placeholder + + @Slot(int) + def on_thumbnail_selected(self, media_id: int): + media = self.db.get_media(media_id) + if media: + self.split_view.set_reference_image(media['media_path']) + + # --- Slots for CameraManager --- + + @Slot(list) + def on_cameras_detected(self, cameras: list[dict]): + """Handles the list of detected cameras.""" + print("Detected cameras:", cameras) + self.welcome_view.set_info_text(f"Detected {len(cameras)} cameras.") + # Populate a combobox in the UI here + # self.view.camera_combobox.clear() + # for camera in cameras: + # self.view.camera_combobox.addItem(camera['name'], userData=camera['id']) + + @Slot(QPixmap) + def on_frame_ready(self, pixmap: QPixmap): + """Displays a new frame from the camera.""" + self.split_view.set_live_image(pixmap) + + @Slot(str) + def on_camera_error(self, error_message: str): + """Shows an error message from the camera.""" + print(f"Camera Error: {error_message}") + self.welcome_view.set_error_text(error_message) + + @Slot() + def on_camera_started(self): + """Updates UI when the camera stream starts.""" + # self.split_view.show_live_view() + self.welcome_view.set_button_text("Stop Camera") + # Re-route button click to stop the camera + self.welcome_view.camera_start_btn.clicked.disconnect() + self.welcome_view.camera_start_btn.clicked.connect(self.stop_liveview) - def start_camera(self): - pass + @Slot() + def on_camera_stopped(self): + """Updates UI when the camera stream stops.""" + # self.split_view.show_placeholder() + self.welcome_view.set_button_text("Start Camera") + # Re-route button click to start the camera + self.welcome_view.camera_start_btn.clicked.disconnect() + self.welcome_view.camera_start_btn.clicked.connect(self.start_liveview) - def load_colors(self) -> None: - colors = self.db.get_all_colors() - print("Loaded colors:", colors) - self.color_list.set_colors(colors) + # --- UI Actions --- + def start_liveview(self): + """Starts the camera feed.""" + detected_cameras = self.camera_manager.get_detected_cameras() + if not detected_cameras: + self.on_camera_error("No cameras detected.") + return + + # For now, just start the first detected camera. + # In a real app, you'd get the selected camera ID from the UI. + camera_id = detected_cameras[0]['id'] + self.camera_manager.start_camera(camera_id) - def on_color_selected(self, color_name: str): - print(f"Wybrano kolor: {color_name}") - color_id = self.db.get_color_id(color_name) - if color_id is not None: - media_items = self.db.get_media_for_color(color_id) - print(f"Media dla koloru {color_name} (ID: {color_id}):", media_items) + def stop_liveview(self): + """Stops the camera feed.""" + self.camera_manager.stop_camera() - self.thumbnail_list.list_widget.clear() - for media in media_items: - if media['file_type'] == 'photo': - file_name = Path(media['media_path']).name - self.thumbnail_list.add_thumbnail(media['media_path'], file_name, media['id']) - else: - print(f"Nie znaleziono koloru o nazwie: {color_name}") - - def on_edit_color(self, color_name: str): - print(f"Edycja koloru: {color_name}") - - def on_thumbnail_selected(self, media_id: int): - media = self.db.get_media(media_id) - if media: - print(f"Wybrano miniaturę o ID: {media_id}, ścieżka: {media['media_path']}") - self.split_view.set_reference_image(media['media_path']) - else: - print(f"Nie znaleziono mediów o ID: {media_id}") - - def take_photo(self): - print("Robienie zdjęcia...") - self.split_view.toglle_live_view() - - def start_liveview(self): - pass - # self.manager.start_camera() - # self.manager.start_stream() - - def shutdown(self): - pass - # self.manager.stop() - - - - # @Slot(list) - def on_cameras_detected(self, cameras: list[dict]): - print("Wykryto kamery:", cameras) - # Tutaj zaktualizuj swój ComboBox w UI, np.: - # self.main_window.camera_combobox.clear() - # for camera in cameras: - # self.main_window.camera_combobox.addItem(camera['name'], userData=camera['id']) - - # @Slot(QPixmap) - def on_frame_ready(self, pixmap: QPixmap): - # Tutaj zaktualizuj widget wyświetlający obraz, np. QLabel - # self.main_window.video_label.setPixmap(pixmap) - pass - - # @Slot(str) - def on_camera_error(self, error_message: str): - print(f"Błąd kamery: {error_message}") - # Wyświetl błąd w UI, np. w status barze - # self.main_window.statusBar().showMessage(error_message, 5000) - - # @Slot() - def on_camera_started(self): - # Zmień stan UI, np. tekst przycisku na "Stop" - # self.main_window.toggle_camera_button.setText("Stop") - pass - - # @Slot() - def on_camera_stopped(self): - # Zmień stan UI, np. tekst przycisku na "Start" - # self.main_window.toggle_camera_button.setText("Start") - pass - - def toggle_camera(self): - # Logika do przełączania start/stop - if self.camera_manager.get_active_camera_info(): - self.camera_manager.stop_camera() - else: - # Pobierz ID kamery z ComboBoxa - # camera_id = self.main_window.camera_combobox.currentData() - # if camera_id: - # self.camera_manager.start_camera(camera_id) - pass - - def on_camera_selected(self, index: int): - # Automatycznie uruchom kamerę po wybraniu z listy - # camera_id = self.main_window.camera_combobox.itemData(index) - # if camera_id: - # self.camera_manager.start_camera(camera_id) - pass - - def cleanup(self): - # Wywołaj to przy zamykaniu aplikacji - self.camera_manager.shutdown() \ No newline at end of file + def take_photo(self): + """Takes a photo with the active camera.""" + print("Taking photo...") # Placeholder + # This needs to be implemented in CameraManager and called here. + # e.g., self.camera_manager.take_photo() + self.split_view.toggle_live_view() # This seems like a UI toggle, maybe rename? \ No newline at end of file