1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
"""
ui/config_dialog.py — Device configuration dialog (tabbed).
"""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTabWidget,
QWidget, QFormLayout, QGroupBox, QScrollArea,
QLabel, QLineEdit, QDoubleSpinBox, QCheckBox,
QPushButton,
)
from PyQt6.QtCore import Qt
class DeviceConfigDialog(QDialog):
def __init__(self, device, parent=None):
super().__init__(parent)
self.device = device
self.setWindowTitle(f"Configure — {device.info.name} [{device.info.device_id}]")
self.setMinimumSize(520, 460)
self._build()
def _build(self):
layout = QVBoxLayout(self)
layout.setSpacing(8)
tabs = QTabWidget()
# ── Tab 1: Device-specific widget ────────────────────────────
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setWidget(self.device.get_config_widget())
tabs.addTab(scroll, "Hardware / Backend")
# ── Tab 2: Channel settings ───────────────────────────────────
tabs.addTab(self._channel_tab(), "Channels & Alarms")
# ── Tab 3: Device info ────────────────────────────────────────
tabs.addTab(self._info_tab(), "Info")
layout.addWidget(tabs)
btn_row = QHBoxLayout()
btn_row.addStretch()
close_btn = QPushButton("Close")
close_btn.setDefault(True)
close_btn.clicked.connect(self.accept)
btn_row.addWidget(close_btn)
layout.addLayout(btn_row)
def _channel_tab(self):
w = QScrollArea()
w.setWidgetResizable(True)
container = QWidget()
layout = QVBoxLayout(container)
for ch in self.device.info.channels:
grp = QGroupBox(f"{ch.channel_id} — {ch.name}")
form = QFormLayout(grp)
name_e = QLineEdit(ch.name)
unit_e = QLineEdit(ch.unit)
en_chk = QCheckBox()
en_chk.setChecked(ch.enabled)
lo = QDoubleSpinBox(); lo.setRange(-1e9, 1e9); lo.setValue(ch.alarm_low or 0.0)
hi = QDoubleSpinBox(); hi.setRange(-1e9, 1e9); hi.setValue(ch.alarm_high or 100.0)
form.addRow("Name:", name_e)
form.addRow("Unit:", unit_e)
form.addRow("Enabled:", en_chk)
form.addRow("Alarm Low:", lo)
form.addRow("Alarm High:", hi)
apply = QPushButton("Apply")
apply.setObjectName("applyButton")
def _make_apply(c, ne, ue, ec, ls, hs):
def _do():
c.name = ne.text()
c.unit = ue.text()
c.enabled = ec.isChecked()
c.alarm_low = ls.value()
c.alarm_high = hs.value()
return _do
apply.clicked.connect(_make_apply(ch, name_e, unit_e, en_chk, lo, hi))
form.addRow(apply)
layout.addWidget(grp)
layout.addStretch()
w.setWidget(container)
return w
def _info_tab(self):
w = QWidget()
form = QFormLayout(w)
info = self.device.info
def _ro(v):
e = QLineEdit(str(v)); e.setReadOnly(True); return e
form.addRow("Device ID:", _ro(info.device_id))
form.addRow("Name:", _ro(info.name))
form.addRow("Type:", _ro(info.device_type))
form.addRow("Description:", _ro(info.description))
form.addRow("Manufacturer:", _ro(info.manufacturer))
form.addRow("Model:", _ro(info.model))
form.addRow("Version:", _ro(info.version))
form.addRow("Status:", _ro(self.device.status.value))
form.addRow("Channels:", _ro(len(info.channels)))
return w
|