fuck yeah!

This commit is contained in:
Vic Sergeev 2026-06-10 17:33:12 +03:00
parent ccb53d9091
commit da10f5e132
44 changed files with 3260 additions and 448 deletions

251
views/main_window.py Normal file
View file

@ -0,0 +1,251 @@
"""
Главное окно приложения - содержит меню, панели и canvas
"""
from PySide6.QtWidgets import (
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QSplitter, QMenuBar, QMenu, QStatusBar, QMessageBox,
QFileDialog, QToolBar, QFrame, QScrollArea, QLabel
)
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QAction, QKeySequence
from views.layer_widget import LayerWidget
from views.canvas_widget import SolarCanvas
from views.control_panel import ControlPanel
from views.timelapse_dialog import TimelapseDialog
from views.metadata_viewer import MetadataViewer
class MainWindow(QMainWindow):
"""Главное окно приложения"""
def __init__(self, controller):
super().__init__()
self.controller = controller
self.init_ui()
def init_ui(self):
"""Инициализация пользовательского интерфейса"""
self.setWindowTitle("Helioviewer Solar Viewer - Профессиональный просмотрщик снимков Солнца")
self.setMinimumSize(1200, 800)
# Центральный виджет
central_widget = QWidget()
self.setCentralWidget(central_widget)
# Основной layout
main_layout = QHBoxLayout(central_widget)
main_layout.setContentsMargins(0, 0, 0, 0)
# Создаем сплиттер для левой панели и canvas
splitter = QSplitter(Qt.Orientation.Horizontal)
main_layout.addWidget(splitter)
# Левая панель (с прокруткой)
left_panel = self.create_left_panel_with_scroll()
splitter.addWidget(left_panel)
# Устанавливаем начальную ширину сплиттера
splitter.setSizes([400, self.width() - 400])
# Правая область (canvas)
right_area = self.create_right_area()
splitter.addWidget(right_area)
# Создаем меню
self.create_menu_bar()
# Создаем статус бар
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
self.status_bar.showMessage("Готов к работе")
# Добавляем тулбар для быстрого доступа
self.create_toolbar()
def create_left_panel_with_scroll(self) -> QWidget:
"""
Создает левую панель с прокруткой, где все виджеты равномерно распределяют пространство
"""
# Внешний контейнер для скролла
scroll_container = QWidget()
scroll_layout = QVBoxLayout(scroll_container)
scroll_layout.setContentsMargins(0, 0, 0, 0)
# Создаем QScrollArea
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True) # Позволяет виджету изменять размер
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
scroll_area.setStyleSheet("""
QScrollArea {
border: none;
background-color: #2b2b2b;
}
QScrollBar:vertical {
background-color: #2b2b2b;
width: 12px;
border-radius: 6px;
}
QScrollBar::handle:vertical {
background-color: #555;
border-radius: 6px;
min-height: 20px;
}
QScrollBar::handle:vertical:hover {
background-color: #777;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0px;
}
""")
# Внутренний контейнер для всех виджетов
content_widget = QWidget()
content_widget.setStyleSheet("background-color: #2b2b2b;")
layout = QVBoxLayout(content_widget)
layout.setSpacing(10)
layout.setContentsMargins(10, 10, 10, 10)
# Панель управления (выбор даты, спектра)
self.control_panel = ControlPanel(self.controller)
layout.addWidget(self.control_panel, 1) # stretch factor = 1
# Разделитель
layout.addWidget(self.create_separator())
# Заголовок слоев
title_layers = self.create_section_title("📁 Слои изображений")
layout.addWidget(title_layers)
# Виджет слоев - будет занимать столько места, сколько нужно
self.layer_widget = LayerWidget(self.controller)
layout.addWidget(self.layer_widget, 2) # stretch factor = 2 (больше места)
# Разделитель
layout.addWidget(self.create_separator())
# Заголовок метаданных
title_metadata = self.create_section_title("📊 Метаданные FITS")
layout.addWidget(title_metadata)
# Просмотрщик метаданных
self.metadata_viewer = MetadataViewer()
layout.addWidget(self.metadata_viewer, 1) # stretch factor = 1
# Растягивающийся спейсер внизу (опционально)
layout.addStretch()
# Устанавливаем content_widget в scroll_area
scroll_area.setWidget(content_widget)
# Добавляем scroll_area в контейнер
scroll_layout.addWidget(scroll_area)
return scroll_container
def create_separator(self) -> QFrame:
"""Создает линию-разделитель"""
separator = QFrame()
separator.setFrameShape(QFrame.Shape.HLine)
separator.setFrameShadow(QFrame.Shadow.Sunken)
separator.setStyleSheet("background-color: #555; max-height: 1px;")
return separator
def create_section_title(self, title: str) -> QLabel:
"""Создает заголовок секции"""
label = QLabel(title)
label.setStyleSheet("""
font-weight: bold;
font-size: 14px;
padding: 8px 5px;
background-color: #3c3c3c;
border-radius: 4px;
margin-top: 5px;
margin-bottom: 5px;
""")
label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
return label
def create_right_area(self) -> QWidget:
"""Создает правую область с canvas"""
area = QWidget()
layout = QVBoxLayout(area)
layout.setContentsMargins(0, 0, 0, 0)
# Canvas для отображения изображений
self.canvas = SolarCanvas(self.controller)
layout.addWidget(self.canvas)
return area
def create_menu_bar(self):
"""Создает меню приложения"""
menubar = self.menuBar()
# Меню Файл
file_menu = menubar.addMenu("📁 Файл")
# Действия для меню Файл
self.setup_action = QAction("⚙️ Настройки", self)
self.exit_action = QAction("🚪 Выход", self)
self.exit_action.setShortcut(QKeySequence.StandardKey.Quit)
self.exit_action.triggered.connect(self.close)
file_menu.addAction(self.setup_action)
file_menu.addSeparator()
file_menu.addAction(self.exit_action)
# Меню Инструменты
tools_menu = menubar.addMenu("🛠️ Инструменты")
self.timelapse_action = QAction("🎬 Таймлапс...", self)
self.timelapse_action.triggered.connect(self.open_timelapse_dialog)
tools_menu.addAction(self.timelapse_action)
# Меню Справка
help_menu = menubar.addMenu("❓ Справка")
about_action = QAction(" О программе", self)
about_action.triggered.connect(self.show_about)
help_menu.addAction(about_action)
def create_toolbar(self):
"""Создает панель инструментов"""
toolbar = QToolBar("Быстрый доступ")
self.addToolBar(toolbar)
toolbar.setIconSize(QSize(24, 24))
def open_timelapse_dialog(self):
"""Открывает диалог создания таймлапса"""
dialog = TimelapseDialog(self.controller, self)
dialog.exec()
def show_about(self):
"""Показывает информацию о программе"""
QMessageBox.about(
self,
"О программе",
"Helioviewer Solar Viewer v1.0\n\n"
"Профессиональный просмотрщик снимков Солнца\n"
"Использует данные Helioviewer API\n\n"
"Возможности:\n"
"• Загрузка снимков в различных спектрах\n"
"• Многослойный режим с наложением\n"
"• Создание таймлапс-анимаций\n"
"• Просмотр FITS-метаданных\n\n"
"© 2024 SolarViewer Team"
)
def update_status(self, message: str, timeout: int = 3000):
"""Обновляет статус в статус-баре"""
self.status_bar.showMessage(message, timeout)
def update_layer_list(self, layers):
"""Обновляет список слоев"""
self.layer_widget.update_layers(layers)
def get_control_panel(self):
"""Возвращает панель управления"""
return self.control_panel