fuck yeah!
This commit is contained in:
parent
ccb53d9091
commit
da10f5e132
44 changed files with 3260 additions and 448 deletions
191
controllers/app_controller.py
Normal file
191
controllers/app_controller.py
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
"""
|
||||
Главный контроллер приложения - связывает модель и представление
|
||||
"""
|
||||
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue