diff options
Diffstat (limited to 'ui/alarm_panel.py')
| -rw-r--r-- | ui/alarm_panel.py | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/ui/alarm_panel.py b/ui/alarm_panel.py new file mode 100644 index 0000000..1270aff --- /dev/null +++ b/ui/alarm_panel.py @@ -0,0 +1,85 @@ +""" +ui/alarm_panel.py — Alarm event log. +""" + +from datetime import datetime +from PyQt6.QtWidgets import ( + QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QScrollArea, QFrame, QPushButton, +) +from PyQt6.QtCore import Qt + + +class AlarmRow(QFrame): + def __init__(self, dev_id: str, ch_id: str, value: float, kind: str): + super().__init__() + self.setObjectName("alarmEntry") + color = "#ef4444" if kind == "high" else "#f59e0b" + arrow = "▲" if kind == "high" else "▼" + self.setStyleSheet(f"QFrame#alarmEntry {{ border-left: 3px solid {color}; }}") + + ts_str = datetime.now().strftime("%H:%M:%S.%f")[:11] + layout = QHBoxLayout(self) + layout.setContentsMargins(8, 3, 8, 3) + + msg = QLabel(f"{arrow} {dev_id} / {ch_id} = {value:.4f} [{kind.upper()}]") + msg.setObjectName("alarmMsg") + ts = QLabel(ts_str) + ts.setObjectName("alarmTs") + + layout.addWidget(msg, 1) + layout.addWidget(ts) + + +class AlarmPanel(QWidget): + def __init__(self): + super().__init__() + self._count = 0 + self._build() + + def _build(self): + layout = QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + + hdr_w = QWidget() + hdr_w.setObjectName("alarmHeaderWidget") + hdr_lay = QHBoxLayout(hdr_w) + hdr_lay.setContentsMargins(0, 0, 4, 0) + hdr = QLabel(" ALARMS") + hdr.setObjectName("panelHeader") + hdr.setMinimumHeight(28) + hdr_lay.addWidget(hdr, 1) + clr = QPushButton("Clear") + clr.setObjectName("clearAlarmsBtn") + clr.clicked.connect(self.clear) + hdr_lay.addWidget(clr) + layout.addWidget(hdr_w) + + self._scroll = QScrollArea() + self._scroll.setWidgetResizable(True) + self._container = QWidget() + self._inner = QVBoxLayout(self._container) + self._inner.setContentsMargins(4, 4, 4, 4) + self._inner.setSpacing(2) + self._inner.addStretch() + self._scroll.setWidget(self._container) + layout.addWidget(self._scroll) + + def add_alarm(self, dev_id: str, ch_id: str, value: float, kind: str): + row = AlarmRow(dev_id, ch_id, value, kind) + self._inner.insertWidget(0, row) + self._count += 1 + # Cap at 300 entries + if self._count > 300: + item = self._inner.takeAt(self._inner.count() - 2) + if item and item.widget(): + item.widget().deleteLater() + self._count -= 1 + + def clear(self): + while self._inner.count() > 1: + item = self._inner.takeAt(0) + if item and item.widget(): + item.widget().deleteLater() + self._count = 0 |
