129 lines
3.7 KiB
Python
129 lines
3.7 KiB
Python
import sys
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QApplication,
|
|
QMainWindow,
|
|
QWidget,
|
|
QVBoxLayout,
|
|
QHBoxLayout, QDialog,
|
|
)
|
|
|
|
from PyQt6.QtCore import Qt
|
|
|
|
import config
|
|
from detektor_data import generate_data
|
|
from detektor_plot import DetektorPlot
|
|
from detektor_region import DetektorRegion
|
|
from channels_menu import ChannelsMenu
|
|
from chart_menu import ChartMenu
|
|
from data_menu import DataMenu
|
|
from menubar import Menubar
|
|
from quit_dialog import QuitDialog
|
|
from callbacks import CallbackDispatcher, CallbackType
|
|
from open_file import file_opener
|
|
from detektor_data import DetektorContainer
|
|
|
|
|
|
class MainWindow(QMainWindow):
|
|
region: DetektorRegion = None
|
|
plot: DetektorPlot = None
|
|
|
|
channels_menu: ChannelsMenu = None
|
|
chart_menu = None
|
|
data_menu = None
|
|
|
|
def __init__(self, data_file: str = None):
|
|
super().__init__()
|
|
|
|
if data_file:
|
|
file_opener(data_file)
|
|
else:
|
|
DetektorContainer().set(
|
|
generate_data(channel_count=3, data_count=200, random_values=True)
|
|
)
|
|
|
|
self.set_base_title()
|
|
self.setGeometry(0, 0, 1800, 800)
|
|
self.showMaximized()
|
|
|
|
CallbackDispatcher().register(CallbackType.FILE_NAME_CHANGED, self.set_base_title)
|
|
|
|
self.main_layout()
|
|
# menubar has to be loaded after layout to have DetektorRegion available
|
|
self.setMenuBar(Menubar(self, self.region))
|
|
|
|
def set_base_title(self):
|
|
"""Set the base window title (default or with filename)."""
|
|
title = f"{config.APP_NAME} {config.APP_VERSION}"
|
|
|
|
if DetektorContainer().get() and DetektorContainer().get().file_path:
|
|
# Append filename if available
|
|
title += f" ({DetektorContainer().get().file_path})"
|
|
|
|
self.setWindowTitle(title)
|
|
|
|
def main_layout(self):
|
|
central_widget = QWidget()
|
|
self.setCentralWidget(central_widget)
|
|
|
|
main_layout = QHBoxLayout()
|
|
central_widget.setLayout(main_layout)
|
|
|
|
self.left_layout(main_layout)
|
|
self.right_layout(main_layout)
|
|
|
|
def left_layout(self, main_layout: QHBoxLayout):
|
|
left_layout = QVBoxLayout()
|
|
main_layout.addLayout(left_layout)
|
|
|
|
self.plot = DetektorPlot(left_layout)
|
|
self.region = DetektorRegion(self.plot)
|
|
|
|
def right_layout(self, main_layout: QHBoxLayout):
|
|
# Create a fixed-size widget to hold the right layout
|
|
right_widget = QWidget()
|
|
right_widget.setFixedWidth(220) # Ensure the width stays fixed
|
|
|
|
# Create a vertical layout inside the fixed-width widget
|
|
right_layout = QVBoxLayout()
|
|
right_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
|
right_widget.setLayout(right_layout) # Set the layout inside the fixed widget
|
|
|
|
# Add the fixed widget (not just the layout) to the main layout
|
|
main_layout.addWidget(right_widget)
|
|
|
|
# Add contents to right_layout
|
|
self.channels_menu = ChannelsMenu(right_layout)
|
|
self.chart_menu = ChartMenu(right_layout, self.plot)
|
|
self.data_menu = DataMenu(right_layout, self.region)
|
|
|
|
def closeEvent(self, event):
|
|
if DetektorContainer().get().data_tainted:
|
|
diag = QuitDialog()
|
|
|
|
if diag.exec() == QDialog.DialogCode.Accepted:
|
|
"""Properly clean up before closing."""
|
|
if self.plot:
|
|
if self.plot.view_box:
|
|
self.plot.view_box.clear()
|
|
self.plot.view_box.deleteLater()
|
|
self.plot.view_box = None
|
|
|
|
if self.plot.graphWidget:
|
|
self.plot.graphWidget.clear() # Clear all items
|
|
self.plot.graphWidget.deleteLater()
|
|
self.plot.graphWidget = None
|
|
|
|
event.accept() # Allow window to close
|
|
else:
|
|
# Prevent closing if "Cancel" was clicked
|
|
event.ignore()
|
|
else:
|
|
# Allow closing if data is not tainted
|
|
event.accept()
|
|
|
|
def create_app(filename: str = None):
|
|
app = QApplication(sys.argv)
|
|
window = MainWindow(filename)
|
|
return app, window
|