cpdctrl-gui/cpdctrl_gui/ui/widgets/settings/measurement_settings.py

175 lines
7.3 KiB
Python

from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QWidget, QRadioButton, QVBoxLayout, QHBoxLayout, QPushButton, QSpinBox, QFileDialog, QLabel
from PyQt6.QtWidgets import QFormLayout, QDoubleSpinBox, QCheckBox, QLineEdit, QGroupBox
from os import path
from cpdctrl_gui.utility.config import AppConfig
from .base import SettingsForm
class DeviceSelection(QGroupBox):
def __init__(self, parent=None):
super().__init__(parent=parent, title="Devices")
self.layout = QFormLayout()
self.setLayout(self.layout)
self.devices_widgets = {}
self._add_device("voltage_measurement", "Voltage Measurement", "N.C.")
self._add_device("led_controller", "Led Controller", "N.C.")
self._add_device("led", "Led Lamp", "Unknown")
# self.layout.addStretch(1)
def _add_device(self, key, label, name):
self.devices_widgets[key] = QLabel(name)
self.layout.addRow(QLabel(label), self.devices_widgets[key])
def set_value(self, key, value):
key = key.replace("device_", "")
if key in self.devices_widgets:
self.devices_widgets[key].setText(value)
else:
raise KeyError(f"Unknown device '{key}'")
class ScriptSelection(QGroupBox):
loadScript = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent=parent, title="LED Script")
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)
# signal when changed
self.w_constant_value.valueChanged.connect(lambda: self.loadScript.emit())
# 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()
last_dir = AppConfig.MAIN_CFG.get_or("tmp_last_script_dir", "")
file_path, _ = QFileDialog.getOpenFileName(self, "Open Script File", last_dir, "All Files (*);;Text files (*.led)")
if file_path:
dir_name = path.dirname(file_path)
AppConfig.MAIN_CFG.set("tmp_last_script_dir", dir_name)
self.file_path = file_path
self.w_script_file.setText(self.file_path)
# signal the change
self.loadScript.emit()
def get_script(self):
if self.radio_script_file.isChecked():
return self.file_path
else:
return int(self.w_constant_value.value())
def get_script_type(self):
if self.radio_script_file.isChecked():
return "file"
else:
return "constant"
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)
# devices
self.w_device_selection = DeviceSelection()
self.l_vbox.addWidget(self.w_device_selection)
# - script
self.w_led_script_load = ScriptSelection()
self.l_vbox.addWidget(self.w_led_script_load)
# key-value stuff in a form
self.w_form = SettingsForm(AppConfig.MEAS_CFG)
self.l_vbox.addWidget(self.w_form)
self.w_form.add_form_row("name", "Name", "", QLineEdit(self), "Name of the measurement")
w_box_interval = QDoubleSpinBox(self)
w_box_interval.setDecimals(2)
w_box_interval.setMinimum(0.01)
w_box_interval.setSingleStep(0.1)
self.w_form.add_form_row("interval", "Interval [s]", 1.0, w_box_interval, "Amount of seconds to wait between voltage measurements and LED device updates")
w_box_max_measurements = QSpinBox(self)
w_box_max_measurements.setMaximum(2147483647) # max int32
w_box_max_measurements.setMinimum(0) # 0 for infinite measurements
self.w_form.add_form_row("max_measurements", "Max Measurements", 0, w_box_max_measurements, "Number of measurements to take. Set to 0 for infinite measurements")
self.w_form.add_form_row("stop_on_script_end", "Stop on Script End", False, QCheckBox(self), "Stop measurement when LED script ends")
self.w_form.add_form_row("use_buffer", "Use Buffer", False, QCheckBox(self), "If available, use the voltage device buffer for more accurate measurement timings.\nLeads to a lower accuracy of LED update timings, up to 1*interval")
w_box_flush_after = QSpinBox(self)
w_box_flush_after.setMaximum(2147483647) # max int32
w_box_flush_after.setSingleStep(500)
self.w_form.add_form_row("flush_after", "Flush-Data Interval", 0, w_box_flush_after, "Number of measurements to take before writing the data to an intermediate file")
self.w_form.add_form_row("auto_add_metadata", "Auto-add Metadata", True, QCheckBox(self), "Automatically add measurement metadata to the data file.\nThis includes: device names, measurement mode, measurement interval, start and stop times, led script")
self.l_vbox.addStretch(1)
def set_value(self, key, value):
if key in self.w_form:
self.w_form.set_value(key, value)
elif key.startswith("device_"):
self.w_device_selection.set_value(key, value)
else:
raise ValueError(f"Unknown key: {key}")
def get_value(self, key):
if key in self.w_form:
return self.w_form.get_value(key)
elif key == "led_script":
return self.w_led_script_load.get_script()
elif key == "led_script_type":
return self.w_led_script_load.get_script_type()
else:
raise ValueError(f"Unknown key: {key}")