from PyQt6.QtWidgets import QWidget, QRadioButton, QVBoxLayout, QHBoxLayout, QPushButton, QSpinBox, QFileDialog, QLabel from PyQt6.QtWidgets import QFormLayout, QDoubleSpinBox, QCheckBox 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.load_button = QPushButton("Load from file") self.load_button.clicked.connect(self.load_file) # QSpinBox for constant value self.spin_box = QSpinBox() self.spin_box.setRange(0, 100) # Layout for radio buttons radio_layout = QHBoxLayout() radio_layout.addWidget(self.radio_script_file) radio_layout.addWidget(self.radio_constant_value) # Layout for load button and spin box input_layout = QHBoxLayout() input_layout.addWidget(self.load_button) input_layout.addWidget(self.spin_box) # Add layouts to main layout self.layout.addLayout(radio_layout) self.layout.addLayout(input_layout) self.setLayout(self.layout) # Initial state self.radio_script_file.setChecked(True) self.on_radio_button_toggled() self.layout.addStretch(1) def on_radio_button_toggled(self): if self.radio_script_file.isChecked(): self.load_button.setEnabled(True) self.spin_box.setEnabled(False) else: self.load_button.setEnabled(False) self.spin_box.setEnabled(True) def load_file(self): # options = QFileDialog.Options() file_name, _ = QFileDialog.getOpenFileName(self, "Open Script File", "", "All Files (*);;Text files (*.led)") if file_name: with open(file_name, 'r') as file: self.file_content = file.read() def get_script(self): if self.radio_script_file.isChecked(): return self.file_content else: return self.spin_box.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(ScriptSelection()) # 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") 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])}") else: raise ValueError(f"Unknown key: {key}")