summaryrefslogtreecommitdiff
path: root/daq_system/ui/main_window.py
diff options
context:
space:
mode:
Diffstat (limited to 'daq_system/ui/main_window.py')
-rw-r--r--daq_system/ui/main_window.py228
1 files changed, 0 insertions, 228 deletions
diff --git a/daq_system/ui/main_window.py b/daq_system/ui/main_window.py
deleted file mode 100644
index 8b602d1..0000000
--- a/daq_system/ui/main_window.py
+++ /dev/null
@@ -1,228 +0,0 @@
-"""
-ui/main_window.py
-
-Main application window. Hosts the left sidebar (device list),
-center strip chart, right panel (numeric readouts + alarms).
-"""
-
-from PyQt6.QtWidgets import (
- QMainWindow, QWidget, QHBoxLayout, QVBoxLayout,
- QSplitter, QStatusBar, QLabel, QPushButton,
- QToolBar, QMessageBox, QFileDialog
-)
-from PyQt6.QtCore import Qt, QTimer, pyqtSlot
-from PyQt6.QtGui import QAction, QIcon, QFont
-
-from devices.analog_input import AnalogInputDevice
-from devices.digital_io import DigitalIODevice
-from devices.temperature import TemperatureDevice
-from devices.serial_device import SerialDevice
-from devices.device_registry import DeviceRegistry
-from core.acquisition import AcquisitionEngine
-
-from ui.device_panel import DevicePanel
-from ui.strip_chart import StripChartWidget
-from ui.readout_panel import ReadoutPanel
-from ui.alarm_panel import AlarmPanel
-from ui.config_dialog import DeviceConfigDialog
-
-
-class MainWindow(QMainWindow):
- def __init__(self):
- super().__init__()
- self.setWindowTitle("LabDAQ — Data Acquisition System")
- self.setMinimumSize(1280, 780)
-
- self.registry = DeviceRegistry()
- self.engine = AcquisitionEngine(poll_interval_ms=100)
- self._running = False
-
- self._init_default_devices()
- self._build_ui()
- self._connect_signals()
-
- # ------------------------------------------------------------------ #
- # Default demo configuration #
- # ------------------------------------------------------------------ #
-
- def _init_default_devices(self):
- ai = AnalogInputDevice(device_id="ai_0", num_channels=4, simulate=True)
- ai.connect()
- temp = TemperatureDevice(device_id="temp_0", num_channels=3, simulate=True)
- temp.connect()
- dio = DigitalIODevice(device_id="dio_0", num_inputs=4, num_outputs=4, simulate=True)
- dio.connect()
-
- for dev in [ai, temp, dio]:
- self.registry.add_instance(dev)
- self.engine.add_device(dev)
-
- # ------------------------------------------------------------------ #
- # UI construction #
- # ------------------------------------------------------------------ #
-
- def _build_ui(self):
- # ---- Toolbar ----
- toolbar = QToolBar("Main")
- toolbar.setMovable(False)
- toolbar.setObjectName("mainToolbar")
- self.addToolBar(toolbar)
-
- self.run_btn = QPushButton("▶ RUN")
- self.run_btn.setObjectName("runButton")
- self.run_btn.setCheckable(True)
- self.run_btn.clicked.connect(self._toggle_run)
-
- self.log_btn = QPushButton("⬤ LOG")
- self.log_btn.setObjectName("logButton")
- self.log_btn.setCheckable(True)
- self.log_btn.setEnabled(False)
- self.log_btn.clicked.connect(self._toggle_log)
-
- add_dev_btn = QPushButton("+ Device")
- add_dev_btn.setObjectName("addDeviceButton")
- add_dev_btn.clicked.connect(self._add_device)
-
- toolbar.addWidget(self.run_btn)
- toolbar.addSeparator()
- toolbar.addWidget(self.log_btn)
- toolbar.addSeparator()
- toolbar.addWidget(add_dev_btn)
-
- # Spacer
- spacer = QWidget()
- spacer.setSizePolicy(
- spacer.sizePolicy().horizontalPolicy(),
- spacer.sizePolicy().verticalPolicy()
- )
- from PyQt6.QtWidgets import QSizePolicy
- spacer.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
- toolbar.addWidget(spacer)
-
- self.time_label = QLabel("00:00:00")
- self.time_label.setObjectName("timeLabel")
- toolbar.addWidget(self.time_label)
-
- # ---- Central layout ----
- central = QWidget()
- self.setCentralWidget(central)
- root = QHBoxLayout(central)
- root.setContentsMargins(0, 0, 0, 0)
- root.setSpacing(0)
-
- splitter = QSplitter(Qt.Orientation.Horizontal)
- splitter.setHandleWidth(4)
-
- # Left: device panel
- self.device_panel = DevicePanel(self.registry, self.engine)
- self.device_panel.setMinimumWidth(200)
- splitter.addWidget(self.device_panel)
-
- # Center: strip chart
- self.strip_chart = StripChartWidget(self.engine, self.registry)
- splitter.addWidget(self.strip_chart)
-
- # Right: readouts + alarms
- right_panel = QWidget()
- right_layout = QVBoxLayout(right_panel)
- right_layout.setContentsMargins(0, 0, 0, 0)
- right_layout.setSpacing(0)
-
- self.readout_panel = ReadoutPanel(self.registry)
- self.alarm_panel = AlarmPanel()
-
- right_splitter = QSplitter(Qt.Orientation.Vertical)
- right_splitter.addWidget(self.readout_panel)
- right_splitter.addWidget(self.alarm_panel)
- right_layout.addWidget(right_splitter)
-
- right_panel.setMinimumWidth(220)
- splitter.addWidget(right_panel)
-
- splitter.setSizes([220, 820, 240])
- root.addWidget(splitter)
-
- # ---- Status bar ----
- self.status_bar = QStatusBar()
- self.setStatusBar(self.status_bar)
- self._status_lbl = QLabel("Ready")
- self.status_bar.addWidget(self._status_lbl)
-
- # Clock timer
- self._elapsed = 0
- self._clock = QTimer()
- self._clock.setInterval(1000)
- self._clock.timeout.connect(self._tick_clock)
-
- def _connect_signals(self):
- self.engine.alarm_triggered.connect(self._on_alarm)
- self.engine.new_data.connect(self.readout_panel.on_new_data)
- self.engine.new_data.connect(self.strip_chart.on_new_data)
- self.device_panel.config_requested.connect(self._open_config)
-
- # ------------------------------------------------------------------ #
- # Actions #
- # ------------------------------------------------------------------ #
-
- def _toggle_run(self, checked: bool):
- if checked:
- self.engine.start()
- self.run_btn.setText("⏹ STOP")
- self.log_btn.setEnabled(True)
- self._clock.start()
- self._status_lbl.setText("Acquiring data…")
- self._running = True
- else:
- self.engine.stop()
- self.run_btn.setText("▶ RUN")
- self.log_btn.setEnabled(False)
- if self.log_btn.isChecked():
- self.log_btn.setChecked(False)
- self._toggle_log(False)
- self._clock.stop()
- self._status_lbl.setText("Stopped")
- self._running = False
-
- def _toggle_log(self, checked: bool):
- if checked:
- path = self.engine.start_logging()
- self.log_btn.setText(f"⏹ LOGGING")
- self._status_lbl.setText(f"Logging → {path}")
- else:
- self.engine.stop_logging()
- self.log_btn.setText("⬤ LOG")
- self._status_lbl.setText("Log saved.")
-
- def _add_device(self):
- from ui.add_device_dialog import AddDeviceDialog
- dlg = AddDeviceDialog(self.registry, self)
- if dlg.exec():
- dev = dlg.created_device
- if dev:
- self.registry.add_instance(dev)
- self.engine.add_device(dev)
- dev.connect()
- self.device_panel.refresh()
- self.readout_panel.refresh()
- self.strip_chart.refresh()
-
- def _open_config(self, device_id: str):
- dev = self.registry.get_instance(device_id)
- if dev:
- dlg = DeviceConfigDialog(dev, self)
- dlg.exec()
-
- @pyqtSlot(str, str, float, str)
- def _on_alarm(self, device_id: str, channel_id: str, value: float, kind: str):
- self.alarm_panel.add_alarm(device_id, channel_id, value, kind)
-
- def _tick_clock(self):
- self._elapsed += 1
- h = self._elapsed // 3600
- m = (self._elapsed % 3600) // 60
- s = self._elapsed % 60
- self.time_label.setText(f"{h:02d}:{m:02d}:{s:02d}")
-
- def closeEvent(self, event):
- self.engine.stop()
- event.accept()