""" Главный контроллер приложения - связывает модель и представление """ from PySide6.QtCore import QObject, Signal from datetime import datetime from pathlib import Path import numpy as np from models.api_model import HelioviewerAPI from models.image_model import ImageModel from views.main_window import MainWindow from utils.image_processor import ImageProcessor from utils.metadata_parser import MetadataParser class AppController(QObject): """Главный контроллер приложения""" def __init__(self): super().__init__() self.image_model = ImageModel() self.api = HelioviewerAPI() self.main_window = None self.timelapse_controller = None # Подключаем сигналы модели self.image_model.layer_added.connect(self.on_layer_added) self.image_model.layer_removed.connect(self.on_layer_removed) self.image_model.layer_visibility_changed.connect(self.on_layer_visibility_changed) self.image_model.layer_opacity_changed.connect(self.on_layer_opacity_changed) self.image_model.layer_selected.connect(self.on_layer_selected) # Папка для сохранения по умолчанию self.download_folder = Path.home() / "SolarImages" self.download_folder.mkdir(exist_ok=True) def show_main_window(self): """Показывает главное окно""" self.main_window = MainWindow(self) self.main_window.show() # Подключаем сигналы от панели управления control_panel = self.main_window.get_control_panel() control_panel.load_image_requested.connect(self.load_image_from_api) def load_image_from_api(self, source_id: int, date: datetime): """Загружает изображение из API""" self.main_window.update_status(f"Загрузка изображения: {date.strftime('%Y-%m-%d %H:%M')} UTC") # Скачиваем изображение filepath = self.api.download_image(source_id, date, self.download_folder) if filepath: # Загружаем данные изображения img_data = ImageProcessor.load_jp2(str(filepath)) if img_data is not None: # Извлекаем метаданные metadata = MetadataParser.extract_metadata(str(filepath)) # Получаем информацию о спектре source_info = self.api.SOURCES.get(source_id, {}) wavelength = source_info.get("wavelength", "Unknown") # Добавляем слой в модель layer_id = self.image_model.add_layer( filepath, source_id, date, wavelength, img_data, metadata ) self.main_window.update_status(f"✓ Загружено: {filepath.name}") else: self.main_window.update_status("✗ Ошибка обработки изображения") else: self.main_window.update_status("✗ Ошибка загрузки изображения") def on_layer_added(self, layer): """Обработчик добавления слоя""" self.main_window.update_layer_list(self.image_model.get_all_layers()) self.main_window.canvas.set_image(layer.id, layer.image_data) def on_layer_removed(self, layer_id): """Обработчик удаления слоя""" self.main_window.layer_widget.remove_layer(layer_id) self.main_window.canvas.remove_layer(layer_id) if not self.image_model.get_all_layers(): self.main_window.metadata_viewer.clear() def on_layer_visibility_changed(self, layer_id, visible): """Обработчик изменения видимости слоя""" self.main_window.canvas.set_layer_visibility(layer_id, visible) def on_layer_opacity_changed(self, layer_id, opacity): """Обработчик изменения прозрачности слоя""" self.main_window.canvas.set_layer_opacity(layer_id, opacity) def on_layer_selected(self, layer_id): """Обработчик выбора слоя""" for layer in self.image_model.get_all_layers(): if layer.id == layer_id: if layer.metadata: self.main_window.metadata_viewer.display_metadata(layer.metadata) break def set_layer_visibility(self, layer_id, visible): self.image_model.set_layer_visibility(layer_id, visible) def set_layer_opacity(self, layer_id, opacity): self.image_model.set_layer_opacity(layer_id, opacity) def clear_all_layers(self): self.image_model.clear() self.main_window.canvas.clear_all_layers() self.main_window.metadata_viewer.clear() # Добавьте эти методы в класс AppController: def create_timelapse(self, source_id: int, start_date: datetime, end_date: datetime, output_path: Path, fps: int = 10, output_format: str = "mp4"): """Создает таймлапс""" from controllers.timelapse_controller import TimelapseController self.timelapse_controller = TimelapseController() # Подключаем сигналы self.timelapse_controller.progress_updated.connect(self.on_timelapse_progress) self.timelapse_controller.log_message.connect(self.on_timelapse_log) self.timelapse_controller.finished.connect(self.on_timelapse_finished) # Запускаем self.timelapse_controller.create_timelapse( source_id, start_date, end_date, output_path, fps, output_format ) def cancel_timelapse(self): """Отменяет создание таймлапса""" if hasattr(self, 'timelapse_controller'): self.timelapse_controller.cancel() def on_timelapse_progress(self, current, total, message): """Прогресс таймлапса""" if self.main_window: self.main_window.update_status(f"Таймлапс: {message}") def on_timelapse_log(self, message): """Лог таймлапса""" print(f"[Timelapse] {message}") def on_timelapse_finished(self, success, message): """Завершение таймлапса""" if self.main_window: if success: self.main_window.update_status(f"✅ Таймлапс создан") from PySide6.QtWidgets import QMessageBox QMessageBox.information(self.main_window, "Готово", f"Таймлапс сохранен:\n{message}") else: self.main_window.update_status(f"❌ Ошибка: {message}") # Добавьте метод: def create_timelapse(self, source_id, start_date, end_date, output_path, fps=10, output_format="mp4"): """Создает таймлапс""" print(f"[DEBUG] AppController.create_timelapse вызван") from controllers.timelapse_controller import TimelapseController self.timelapse_controller = TimelapseController() # Подключаем сигналы self.timelapse_controller.progress_updated.connect(self.on_timelapse_progress) self.timelapse_controller.log_message.connect(self.on_timelapse_log) self.timelapse_controller.finished.connect(self.on_timelapse_finished) # Запускаем self.timelapse_controller.create_timelapse( source_id, start_date, end_date, output_path, fps, output_format ) print(f"[DEBUG] TimelapseController создан и запущен") def on_timelapse_log(self, message): """Лог таймлапса""" print(f"[TIMELAPSE] {message}") if self.main_window: self.main_window.update_status(f"Таймлапс: {message}") def create_timelapse(self, source_id, start_date, end_date, output_path, fps=10, output_format="mp4"): """Создает таймлапс - заглушка, реальный вызов из диалога""" # Реальная реализация в диалоге pass def cancel_timelapse(self): pass