HelioParser/controllers/app_controller.py
2026-06-10 17:33:12 +03:00

191 lines
No EOL
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Главный контроллер приложения - связывает модель и представление
"""
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