470f8acba3
Bootstrap PySide6 using a clean src/ layout and refactor stream_reader to parse binary data packets asynchronously.
76 lines
2.9 KiB
Python
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())
|