Group settings

This commit is contained in:
CPD 2025-03-26 18:23:01 +01:00
parent 9b3f2af772
commit acdbb7beb1
2 changed files with 90 additions and 30 deletions

View File

@ -9,32 +9,47 @@ class AppSettings(QWidget):
self.setLayout(QVBoxLayout())
self.w_form = SettingsForm(AppConfig.MAIN_CFG)
self.layout().addWidget(self.w_form)
self.w_form.add_group("devices", "Devices")
self.w_form.add_group("interface", "Interface")
self.w_form.add_group("led_script", "LED Script")
self.w_form.add_group("power_switch", "Power Switch")
w_cache_dir = FileSelection(filemode=QFileDialog.FileMode.Directory)
self.w_form.add_form_row("dir_cache", "Cache Directory", "~/.cache/cpdctrl", w_cache_dir, "Directory to store temporary data")
self.w_form.add_form_row("led_device_auto_reconnect", "Autoconnect to last LED Controller", True, QCheckBox(), "Automatically connect to the last used LED Controller")
self.w_form.add_form_row("voltage_measurement_device_auto_reconnect", "Autoconnect to last Voltage Measurement Device", True, QCheckBox(), "Automatically connect to the last used Voltage Measurement Device")
w_plot_n = QSpinBox()
w_plot_n.setMinimum(1000)
w_plot_n.setMaximum(200000)
w_plot_n.setSingleStep(1000)
self.w_form.add_form_row("plot_max_data_points", "Max. Datapoints in the Plot", 20000, w_plot_n, "Maximum number of datapoints in the live plot.\nThis value is limited to ensure performance is not degraded in long measurements")
w_plot_dt = QSpinBox()
w_plot_dt.setMinimum(10)
w_plot_dt.setMaximum(200000)
w_plot_dt.setSingleStep(100)
self.w_form.add_form_row("plot_update_interval_ms", "Plot Update Interval (ms)", 200, w_plot_dt, "Number of milliseconds to wait before updating the live plot")
self.w_form.add_form_row("led_script_watch_file", "Watch Led Script File", False, QCheckBox(), "Watch the LED script file for changes and reload it automatically")
self.w_form.add_form_row("led_script_save_copy", "Copy Led Script to Cache Dir", True, QCheckBox(), "Save the final version of the led script in the cache directory")
self.w_form.add_form_row("metadata_auto_update", "Auto-Update Metadata", True, QCheckBox(), "Allow metadata updates while the program is running")
self.w_form.add_form_row("metadata_auto_add", "Auto-Add Metadata", True, QCheckBox(), "Automatically add measurement metadata to the data file.\nThis includes: device names, measurement mode, measurement interval, start and stop times, led script")
w_usb_switch_exe = FileSelection(filemode=QFileDialog.FileMode.ExistingFile)
self.w_form.add_form_row("power_switch_exe", "Power Switch Executable", "", w_usb_switch_exe, "Path to the USBSwitchCmd executable for the Cleware USB switch\nRequires a relaunch to take effect")
# devices
self.w_form.add_form_row("led_device_auto_reconnect", "Autoconnect to last LED Controller", True, QCheckBox(), "Automatically connect to the last used LED Controller", group="devices")
self.w_form.add_form_row("voltage_measurement_device_auto_reconnect", "Autoconnect to last Voltage Measurement Device", True, QCheckBox(), "Automatically connect to the last used Voltage Measurement Device", group="devices")
w_idle_dt = QSpinBox()
w_idle_dt.setMinimum(10)
w_idle_dt.setMaximum(200000)
w_idle_dt.setSingleStep(10)
self.w_form.add_form_row("idle_update_interval_s", "Device Connection Check Interval (s)", 30, w_plot_dt, "How often to check whether the devices are still connected.\nApplies only when not in a measurement.")
self.w_form.add_form_row("error_show_dialog", "Show Dialog on Error", True, QCheckBox(), "Whether to show a dialog window when uncaught errors occur\nLeave this on.")
self.w_form.add_form_row("error_stack_trace", "Stacktrace in errors", False, QCheckBox(), "Whether to show the call stack in unexpected error messages")
self.w_form.add_form_row("idle_update_interval_s", "Device Connection Check Interval (s)", 30, w_idle_dt, "How often to check whether the devices are still connected.\nApplies only when not in a measurement.", group="devices")
# interface
w_plot_n = QSpinBox()
w_plot_n.setMinimum(1000)
w_plot_n.setMaximum(200000)
w_plot_n.setSingleStep(1000)
self.w_form.add_form_row("plot_max_data_points", "Max. Datapoints in the Plot", 20000, w_plot_n, "Maximum number of datapoints in the live plot.\nThis value is limited to ensure performance is not degraded in long measurements", group="interface")
w_plot_dt = QSpinBox()
w_plot_dt.setMinimum(10)
w_plot_dt.setMaximum(200000)
w_plot_dt.setSingleStep(100)
self.w_form.add_form_row("plot_update_interval_ms", "Plot Update Interval (ms)", 200, w_plot_dt, "Number of milliseconds to wait before updating the live plot", group="interface")
self.w_form.add_form_row("error_show_dialog", "Show Dialog on Error", True, QCheckBox(), "Whether to show a dialog window when uncaught errors occur\nLeave this on.", group="interface")
self.w_form.add_form_row("error_stack_trace", "Stacktrace in errors", False, QCheckBox(), "Whether to show the call stack in unexpected error messages", group="interface")
# led_script
self.w_form.add_form_row("led_script_watch_file", "Watch Led Script File", False, QCheckBox(), "Watch the LED script file for changes and reload it automatically", group="led_script")
self.w_form.add_form_row("led_script_save_copy", "Copy Led Script to Cache Dir", True, QCheckBox(), "Save the final version of the led script in the cache directory", group="led_script")
self.w_form.add_form_row("metadata_auto_update", "Auto-Update Metadata", True, QCheckBox(), "Allow metadata updates while the program is running")
self.w_form.add_form_row("metadata_auto_add", "Auto-Add Metadata", True, QCheckBox(), "Automatically add measurement metadata to the data file.\nThis includes: device names, measurement mode, measurement interval, start and stop times, led script")
# power_switch
w_usb_switch_exe = FileSelection(filemode=QFileDialog.FileMode.ExistingFile)
self.w_form.add_form_row("power_switch_exe", "Power Switch Executable", "", w_usb_switch_exe, "Path to the USBSwitchCmd executable for the Cleware USB switch\nRequires a relaunch to take effect", group="power_switch")
self.w_form.update_alignment()

View File

@ -1,6 +1,7 @@
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QWidget, QLabel, QFormLayout, QSpinBox, QDoubleSpinBox, QLineEdit, QHBoxLayout, QPushButton, QFileDialog, QCheckBox
from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QWidget, QLabel, QFormLayout, QSpinBox, QDoubleSpinBox, QLineEdit, QHBoxLayout, QPushButton, \
QFileDialog, QCheckBox, QVBoxLayout, QGroupBox
from PyQt6.QtCore import pyqtSignal, Qt
from cpdctrl.utility.config_file import ConfigFile
@ -47,14 +48,35 @@ class SettingsForm(QWidget):
"""
def __init__(self, config_file: ConfigFile, parent=None):
super().__init__(parent)
self.setLayout(QFormLayout())
self.ws_form = {}
self.setLayout(QVBoxLayout())
self.ws_form: dict[str, QWidget] = {}
self.ls_form: dict[str, QLabel] = {}
self.ws_groups: dict[str, QFormLayout] = {}
self.config_file = config_file
w_default = QWidget()
w_default.setLayout(QFormLayout())
self.ws_groups["default"] = w_default.layout()
self.layout().addWidget(w_default)
def __contains__(self, item):
return item in self.ws_form
def add_form_row(self, key: str, label: str, default_value, widget: QWidget, tooltip: str = None):
def add_group(self, key, name):
"""
Add a group box
Parameters
----------
key
The key to be used with add_form_row
name
The name to display
"""
w_group = QGroupBox(parent=None, title=name)
w_group.setLayout(QFormLayout())
self.layout().addWidget(w_group)
self.ws_groups[key] = w_group.layout()
def add_form_row(self, key: str, label: str, default_value, widget: QWidget, tooltip: str = None, group:str="default"):
"""
Add a row to the form. Uses the value from the config file corresponding to <key> or the default value.
Parameters
@ -62,15 +84,21 @@ class SettingsForm(QWidget):
key
label: str
Label for the form widget
default_value
widget
default_value:
The default value to use for the widget
widget: QWidget
Widget to add to the form
tooltip
tooltip: str
Tooltip for the widget
group: str
Group to add the row to.
Returns
-------
"""
if not group in self.ws_groups:
raise ValueError(f"Can not add form row '{key}': Group '{group}' does not exist.")
if tooltip: widget.setToolTip(tooltip)
value = self.config_file.get_or(key, default_value)
# set the value depending on the type of the widget
@ -88,8 +116,10 @@ class SettingsForm(QWidget):
widget.textChanged.connect(lambda v: self.value_updated(key, v))
else:
raise ValueError(f"Unknown widget type: {type(widget)}")
self.layout().addRow(QLabel(label), widget)
l_label = QLabel(label)
self.ws_groups[group].addRow(l_label, widget)
self.ws_form[key] = widget
self.ls_form[key] = l_label
def value_updated(self, key, value):
@ -152,3 +182,18 @@ class SettingsForm(QWidget):
raise ValueError(f"Unknown widget type: {type(self.ws_form[key])}")
else:
raise ValueError(f"Unknown key: {key}")
def update_alignment(self):
"""
Give all labels the min width of the widest label,
so that all forms are aligned even when in different group boxes
"""
max_width = 0
for _, l in self.ls_form.items():
w = l.minimumSizeHint().width()
if w > max_width:
max_width = w
for _, l in self.ls_form.items():
l.setMinimumWidth(max_width)