cpdctrl-gui/app/ui/widgets/measurement_settings.py
2025-03-05 12:41:10 +01:00

147 lines
6.1 KiB
Python

from PyQt6.QtWidgets import QWidget, QRadioButton, QVBoxLayout, QHBoxLayout, QPushButton, QSpinBox, QFileDialog, QLabel
from PyQt6.QtWidgets import QFormLayout, QDoubleSpinBox, QCheckBox, QLineEdit
from ...utility.config import AppConfig
class ScriptSelection(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.layout = QVBoxLayout()
# Radio buttons
self.radio_script_file = QRadioButton("Script file")
self.radio_constant_value = QRadioButton("Constant value")
self.radio_script_file.toggled.connect(self.on_radio_button_toggled)
self.radio_constant_value.toggled.connect(self.on_radio_button_toggled)
# Load from file button
self.btn_load_script = QPushButton("Load from file")
self.btn_load_script.clicked.connect(self.load_file)
self.w_script_file = QLineEdit()
self.w_script_file.setEnabled(False)
# QSpinBox for constant value
self.w_constant_value = QSpinBox()
self.w_constant_value.setRange(0, 100)
# Layouts
l_constant_value = QVBoxLayout()
l_constant_value.addWidget(self.radio_constant_value)
l_constant_value.addWidget(self.w_constant_value)
l_file = QVBoxLayout()
l_file.addWidget(self.radio_script_file)
l_file.addWidget(self.btn_load_script)
l_file.addWidget(self.w_script_file)
# Add layouts to main layout
self.layout.addLayout(l_constant_value)
self.layout.addLayout(l_file)
self.setLayout(self.layout)
# Initial state
self.radio_constant_value.setChecked(True)
self.on_radio_button_toggled()
self.layout.addStretch(1)
self.file_path = None
def on_radio_button_toggled(self):
if self.radio_script_file.isChecked():
self.btn_load_script.setEnabled(True)
self.w_constant_value.setEnabled(False)
else:
self.btn_load_script.setEnabled(False)
self.w_constant_value.setEnabled(True)
def load_file(self):
# options = QFileDialog.Options()
file_path, _ = QFileDialog.getOpenFileName(self, "Open Script File", "", "All Files (*);;Text files (*.led)")
if file_path:
self.file_path = file_path
self.w_script_file.setText(self.file_path)
def get_script(self):
if self.radio_script_file.isChecked():
return self.file_path
else:
return int(self.w_constant_value.value())
class MeasurementSettings(QWidget):
"""
Widget allowing the user to set the measurement settings.
It loads the values from AppConfig.MEAS_CFG and automatically
updates the values in AppConfig.MEAS_CFG when the user changes them.
"""
def __init__(self, parent=None):
super().__init__(parent)
self.l_vbox = QVBoxLayout()
# self.label = QLabel("Measurement Settings")
# self.layout.addWidget(self.label)
self.setLayout(self.l_vbox)
self.l_form = QFormLayout()
# - script
self.l_vbox.addWidget(QLabel("LED Script"))
self.w_led_script = ScriptSelection()
self.l_vbox.addWidget(self.w_led_script)
# key-value stuff in a form
self.l_vbox.addLayout(self.l_form)
self.ws_form = {}
self._add_form_field("interval", "Interval [s]", 1.0, QDoubleSpinBox(self), "Amount of seconds to wait between voltage measurements and LED device updates")
self._add_form_field("max_measurements", "Max Measurements", 0, QSpinBox(self), "Number of measurements to take. Set to 0 for infinite measurements")
self._add_form_field("stop_on_script_end", "Stop on Script End", False, QCheckBox(self), "Stop measurement when LED script ends")
self._add_form_field("use_buffer", "Use Buffer", False, QCheckBox(self), "If available, use device buffer for more accurate measurement timings.\nLeads to a lower accuracy of LED update timings, up to 1*interval")
self._add_form_field("flush_after", "Flush after", 0, QSpinBox(self), "Number of measurements to take before writing the data to an intermediate file")
self.l_vbox.addStretch(1)
def _add_form_field(self, key: str, label: str, default_value, widget: QWidget, tooltip: str = None):
if tooltip: widget.setToolTip(tooltip)
value = AppConfig.MEAS_CFG.get_or(key, default_value)
# set the value depending on the type of the widget
if isinstance(widget, QSpinBox) or isinstance(widget, QDoubleSpinBox):
widget.setValue(value)
widget.valueChanged.connect(lambda value: self.value_updated(key, value))
elif isinstance(widget, QCheckBox):
widget.setChecked(value)
widget.stateChanged.connect(lambda value: self.value_updated(key, value))
else:
raise ValueError(f"Unknown widget type: {type(widget)}")
self.l_form.addRow(QLabel(label), widget)
self.ws_form[key] = widget
def value_updated(self, key, value):
AppConfig.MEAS_CFG.set(key, value)
def set_value(self, key, value):
if key in self.ws_form:
# set depending on widget type
if isinstance(self.ws_form[key], QSpinBox) or isinstance(self.ws_form[key], QDoubleSpinBox):
self.ws_form[key].setValue(value)
elif isinstance(self.ws_form[key], QCheckBox):
self.ws_form[key].setChecked(value)
else:
raise ValueError(f"Unknown widget type: {type(self.ws_form[key])}")
else:
raise ValueError(f"Unknown key: {key}")
def get_value(self, key):
if key in self.ws_form:
# get depending on widget type
if isinstance(self.ws_form[key], QSpinBox) or isinstance(self.ws_form[key], QDoubleSpinBox):
return self.ws_form[key].value()
elif isinstance(self.ws_form[key], QCheckBox):
return self.ws_form[key].isChecked()
else:
raise ValueError(f"Unknown widget type: {type(self.ws_form[key])}")
elif key == "led_script":
return self.w_led_script.get_script()
else:
raise ValueError(f"Unknown key: {key}")