Source code for dlab.app

from __future__ import annotations

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QGroupBox,
    QHBoxLayout,
    QLabel,
    QMainWindow,
    QPushButton,
    QSpinBox,
    QVBoxLayout,
    QWidget,
)

from dlab.boot import ROOT, bootstrap
from dlab.hardware.wrappers.pressure_sensor import PressureMonitorWidget
from dlab.utils.log_panel import LogPanel


[docs] class DlabControllerWindow(QMainWindow): """ Main launcher window for lab instrument control. To run Grafana with Prometheus: cd C:\\Prometheus .\\prometheus.exe --config.file=prometheus.yml Grafana credentials: user: admin, password: admin """ def __init__(self, log_panel: LogPanel): super().__init__() self._log = log_panel self._windows: dict[str, QWidget | None] = { "andor": None, "avaspec": None, "powermeter": None, "stage_control": None, "slm": None, "scan": None, "phase_lock": None, } self._daheng_windows: dict[str, QWidget] = {} self._camera_controls: dict[str, QSpinBox] = {} self._setup_ui() def _setup_ui(self): self.setWindowTitle("DlabControllerWindow") self.resize(300, 400) central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # Windows group windows_group = QGroupBox("Windows") view_layout = QVBoxLayout() # Main instrument buttons buttons = [ ("Open SLM Window", self._open_slm_window), ("Open Andor Window", self._open_andor_window), ("Open Avaspec Window", self._open_avaspec_window), ("Open Powermeter Window", self._open_powermeter_window), ("Open Stage Control Window", self._open_stage_control_window), ("Open Scan Window", self._open_scan_window), ("Open Phase Lock Window", self._open_phase_lock_window), ] for label, callback in buttons: btn = QPushButton(label) btn.clicked.connect(callback) view_layout.addWidget(btn) # Daheng camera controls for i, name in enumerate( ["DahengCam_1", "DahengCam_2", "DahengCam_3"], start=1 ): self._add_daheng_control(view_layout, name, default_index=i) windows_group.setLayout(view_layout) main_layout.addWidget(windows_group) # Grafana dashboard link dashboard_url = ( "http://localhost:3000/d/ad6bbh8/pressure-dashboard" "?orgId=1&from=now-30m&to=now&timezone=browser&refresh=auto" ) path_label = QLabel(f'<a href="{dashboard_url}">Open Pressure Dashboard</a>') path_label.setOpenExternalLinks(True) main_layout.addWidget(path_label) main_layout.addStretch(1) # Log toggle button self._log_button = QPushButton("Hide Log") self._log_button.clicked.connect(self._toggle_log) main_layout.addWidget(self._log_button) self._setup_pressure_log() def _add_daheng_control(self, layout: QVBoxLayout, name: str, default_index: int): """Add a Daheng camera control group with index spinbox.""" box = QGroupBox(name) h_layout = QHBoxLayout() spinbox = QSpinBox() spinbox.setRange(1, 5) spinbox.setValue(default_index) h_layout.addWidget(QLabel("Index:")) h_layout.addWidget(spinbox) button = QPushButton("Open") button.clicked.connect( lambda _, n=name, sb=spinbox: self._open_daheng_window(n, sb.value()) ) h_layout.addWidget(button) box.setLayout(h_layout) layout.addWidget(box) self._camera_controls[name] = spinbox def _setup_pressure_log(self): self._pressure_monitor = PressureMonitorWidget(self, log_panel=self._log) def _toggle_log(self): if self._log.isVisible(): self._log.hide() self._log_button.setText("Show Log") else: self._log.show() self._log_button.setText("Hide Log") # ------------------------------------------------------------------------- # Generic window management # ------------------------------------------------------------------------- def _open_window( self, key: str, window_class: type, display_name: str, *args, use_destroyed_signal: bool = False, **kwargs, ): """ Open a window if not already open, or bring it to front. Args: key: Key in self._windows dict window_class: The window class to instantiate display_name: Human-readable name for logging use_destroyed_signal: Use 'destroyed' signal instead of 'closed' *args, **kwargs: Passed to window_class constructor """ win = self._windows[key] if win is None: win = window_class(*args, **kwargs) signal = win.destroyed if use_destroyed_signal else win.closed signal.connect( lambda *a, k=key, name=display_name: self._on_window_closed(k, name) ) self._windows[key] = win self._log.log("Window opened.", source=display_name) win.show() win.raise_() win.activateWindow() def _on_window_closed(self, key: str, display_name: str): """Handle window close event.""" self._windows[key] = None self._log.log("Window closed.", source=display_name) # ------------------------------------------------------------------------- # Individual window openers # ------------------------------------------------------------------------- def _open_andor_window(self): from dlab.diagnostics.ui.andor_live_window import AndorLiveWindow self._open_window("andor", AndorLiveWindow, "Andor", self._log) def _open_avaspec_window(self): from dlab.diagnostics.ui.avaspec_live_window import AvaspecLiveWindow self._open_window("avaspec", AvaspecLiveWindow, "Avaspec", self._log) def _open_slm_window(self): from dlab.diagnostics.ui.slm_window import SlmWindow self._open_window("slm", SlmWindow, "SLM", self._log) def _open_stage_control_window(self): from dlab.diagnostics.ui.stage_control_window import StageControlWindow self._open_window("stage_control", StageControlWindow, "Stage Control", self._log) def _open_scan_window(self): from dlab.diagnostics.ui.scans.scan_window import ScanWindow self._open_window("scan", ScanWindow, "Scan") def _open_powermeter_window(self): from dlab.diagnostics.ui.powermeter_live_window import PowermeterLiveWindow self._open_window("powermeter", PowermeterLiveWindow, "Powermeter", self._log) def _open_phase_lock_window(self): from dlab.diagnostics.ui.phase_lock_window import AvaspecPhaseLockWindow self._open_window( "phase_lock", AvaspecPhaseLockWindow, "Phase Lock", self._log ) # ------------------------------------------------------------------------- # Daheng camera windows (multiple instances) # ------------------------------------------------------------------------- def _open_daheng_window(self, camera_name: str, index: int): from dlab.diagnostics.ui.daheng_live_window import DahengLiveWindow if camera_name in self._daheng_windows: self._log.log("Window already open.", source=camera_name) win = self._daheng_windows[camera_name] win.show() win.raise_() win.activateWindow() return win = DahengLiveWindow( camera_name=camera_name, fixed_index=index, log_panel=self._log ) win.closed.connect(lambda name=camera_name: self._on_daheng_window_closed(name)) self._daheng_windows[camera_name] = win win.show() win.raise_() win.activateWindow() self._log.log("Window opened.", source=camera_name) def _on_daheng_window_closed(self, camera_name: str): self._daheng_windows.pop(camera_name, None) self._log.log("Window closed.", source=camera_name)
[docs] def main(): CFG = bootstrap(ROOT / "config" / "config.yaml") app = QApplication(sys.argv) log_panel = LogPanel() log_panel.show() window = DlabControllerWindow(log_panel) window.show() sys.exit(app.exec_())
if __name__ == "__main__": main()