Files
pyGUI/src/pygui/__main__.py
T
jack 470f8acba3 feat(core): migrate to src/ package layout and refactor serial transport
Bootstrap PySide6 using a clean src/ layout and refactor stream_reader to parse binary data packets asynchronously.
2026-06-25 13:46:54 -07:00

76 lines
2.9 KiB
Python

import logging
import sys
from pathlib import Path
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle
from PySide6.QtWidgets import QApplication
from pygui.backend.controllers.device_controller import DeviceController
from pygui.backend.controllers.session_controller import SessionController
from pygui.backend.data.file_browser import FileBrowser
from pygui.backend.data.local_settings import LocalSettings
from pygui.backend.data.local_settings_model import LocalSettingsModel
# Importing wafer_map_item + trend_chart_item registers @QmlElement types (QML: import ISC.Wafer).
# ===== Application Entry Point =====
def main() -> int:
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
)
# ===== UI Style Setup =====
# Use a non-native controls style so our custom QML button backgrounds are supported.
QQuickStyle.setStyle("Basic")
# ===== Qt Bootstrap =====
# Minimal Qt bootstrap: load the ISC QML module and exit if it fails.
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
# ===== Shared Models =====
settings_model = LocalSettingsModel()
select_file_dialog_model = FileBrowser()
settings_model.loadSettings()
engine.rootContext().setContextProperty("settingsModel", settings_model)
engine.rootContext().setContextProperty("file_browser", select_file_dialog_model)
# ===== Device Controller (serial comm) =====
data_dir = str(settings_model._data_dir)
raw_settings = LocalSettings.read_settings(data_dir)
device_controller = DeviceController(raw_settings, data_dir)
engine.rootContext().setContextProperty("deviceController", device_controller)
# ===== Session Controller (live/review wafer dashboard) =====
raw_settings_dict = raw_settings.__dict__.copy() if hasattr(raw_settings, '__dict__') else {}
stream_controller = SessionController(settings=raw_settings_dict)
engine.rootContext().setContextProperty("streamController", stream_controller)
# Persist session state back to settings when it changes
def _persist_session_settings():
session_state = stream_controller.collect_settings()
for k, v in session_state.items():
if hasattr(raw_settings, k):
setattr(raw_settings, k, v)
LocalSettings.save_settings(data_dir, raw_settings)
stream_controller.settingsChanged.connect(_persist_session_settings)
# ===== QML Startup =====
# The "ISC" QML module lives alongside this file (src/pygui/ISC), so the
# package directory is the import path the engine searches for qmldir.
engine.addImportPath(Path(__file__).parent)
engine.loadFromModule("ISC", "Main")
# ===== Exit Handling =====
if not engine.rootObjects():
return -1
return app.exec()
if __name__ == "__main__":
sys.exit(main())