fuck yeah!
This commit is contained in:
parent
ccb53d9091
commit
da10f5e132
44 changed files with 3260 additions and 448 deletions
251
views/main_window.py
Normal file
251
views/main_window.py
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue