mirror of
https://github.com/nqrduck/nqrduck-spectrometer.git
synced 2024-12-22 08:17:49 +00:00
commit
cb5df0a9af
3 changed files with 174 additions and 50 deletions
|
@ -2,6 +2,7 @@ import logging
|
|||
from collections import OrderedDict
|
||||
from PyQt6.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||
from nqrduck.module.module_model import ModuleModel
|
||||
from.settings import Setting
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -18,35 +19,7 @@ class BaseSpectrometerModel(ModuleModel):
|
|||
"""
|
||||
settings : OrderedDict
|
||||
pulse_parameter_options : OrderedDict
|
||||
|
||||
class Setting(QObject):
|
||||
"""A setting for the spectrometer is a value that is the same for all events in a pulse sequence.
|
||||
E.g. the number of averages or the number of points in a spectrum.
|
||||
"""
|
||||
settings_changed = pyqtSignal()
|
||||
|
||||
def __init__(self, name : str, default : str, description : str) -> None:
|
||||
"""Initializes the setting.
|
||||
|
||||
Arguments:
|
||||
name (str) -- The name of the setting
|
||||
default (str) -- The default value of the setting
|
||||
description (str) -- The description of the setting
|
||||
"""
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.value = default
|
||||
self.description = description
|
||||
|
||||
@pyqtSlot(str)
|
||||
def on_value_changed(self, value):
|
||||
logger.debug("Setting %s changed to %s", self.name, value)
|
||||
self.value = value
|
||||
self.settings_changed.emit()
|
||||
|
||||
def get_setting(self):
|
||||
return float(self.value)
|
||||
|
||||
|
||||
class PulseParameter:
|
||||
"""A pulse parameter is a value that can be different for each event in a pulse sequence.
|
||||
E.g. the transmit pulse power or the phase of the transmit pulse.
|
||||
|
@ -115,18 +88,11 @@ class BaseSpectrometerModel(ModuleModel):
|
|||
self.settings = OrderedDict()
|
||||
self.pulse_parameter_options = OrderedDict()
|
||||
|
||||
def add_setting(self, name : str, value: str, description : str, category : str) -> None:
|
||||
"""Adds a setting to the spectrometer.
|
||||
|
||||
Arguments:
|
||||
name (str) -- The name of the setting
|
||||
value (str) -- The default value of the setting
|
||||
description (str) -- The description of the setting
|
||||
category (str) -- The category of the setting
|
||||
"""
|
||||
def add_setting(self, setting : Setting, category : str) -> None:
|
||||
|
||||
if category not in self.settings.keys():
|
||||
self.settings[category] = []
|
||||
self.settings[category].append(self.Setting(name, value, description))
|
||||
self.settings[category].append(setting)
|
||||
|
||||
def get_setting_by_name(self, name : str) -> Setting:
|
||||
"""Gets a setting by its name.
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import logging
|
||||
from pathlib import Path
|
||||
from PyQt6.QtWidgets import QWidget, QLabel, QLineEdit, QHBoxLayout, QSizePolicy, QSpacerItem, QVBoxLayout
|
||||
from PyQt6.QtWidgets import QWidget, QLabel, QLineEdit, QHBoxLayout, QSizePolicy, QSpacerItem, QVBoxLayout, QCheckBox, QComboBox
|
||||
from PyQt6.QtGui import QIcon
|
||||
from PyQt6.QtCore import Qt, pyqtSlot
|
||||
from nqrduck.module.module_view import ModuleView
|
||||
from nqrduck.assets.icons import Logos
|
||||
from .settings import FloatSetting, IntSetting, BooleanSetting, SelectionSetting, StringSetting
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -46,18 +47,31 @@ class BaseSpectrometerView(ModuleView):
|
|||
category_layout.addWidget(category_label)
|
||||
for setting in self.module.model.settings[category]:
|
||||
logger.debug("Adding setting to settings view: %s", setting.name)
|
||||
|
||||
|
||||
spacer = QSpacerItem(20, 20)
|
||||
# Create a label for the setting
|
||||
setting_label = QLabel(setting.name)
|
||||
setting_label.setMinimumWidth(200)
|
||||
# Add an QLineEdit for the setting
|
||||
line_edit = QLineEdit(str(setting.value))
|
||||
line_edit.setMinimumWidth(100)
|
||||
# Add a horizontal layout for the setting
|
||||
layout = QHBoxLayout()
|
||||
# Connect the editingFinished signal to the on_value_changed slot of the setting
|
||||
line_edit.editingFinished.connect(lambda x=line_edit, s=setting: s.on_value_changed(x.text()))
|
||||
|
||||
# Depending on the setting type we add different widgets to the view
|
||||
if isinstance(setting, FloatSetting) or isinstance(setting, IntSetting) or isinstance(setting, StringSetting):
|
||||
edit_widget = QLineEdit(str(setting.value))
|
||||
edit_widget.setMinimumWidth(100)
|
||||
# Connect the editingFinished signal to the on_value_changed slot of the setting
|
||||
edit_widget.editingFinished.connect(lambda x=edit_widget, s=setting: s.on_value_changed(x.text()))
|
||||
|
||||
elif isinstance(setting, BooleanSetting):
|
||||
edit_widget = QCheckBox()
|
||||
edit_widget.setChecked(setting.value)
|
||||
edit_widget.stateChanged.connect(lambda x=edit_widget, s=setting: s.on_value_changed(x))
|
||||
|
||||
elif isinstance(setting, SelectionSetting):
|
||||
edit_widget = QComboBox()
|
||||
edit_widget.addItems(setting.options)
|
||||
edit_widget.setCurrentText(setting.value)
|
||||
edit_widget.currentTextChanged.connect(lambda x=edit_widget, s=setting: s.on_value_changed(x))
|
||||
|
||||
|
||||
# Add a icon that can be used as a tooltip
|
||||
if setting.description is not None:
|
||||
logger.debug("Adding tooltip to setting: %s", setting.name)
|
||||
|
@ -68,11 +82,13 @@ class BaseSpectrometerView(ModuleView):
|
|||
icon_label.setFixedSize(icon.availableSizes()[0])
|
||||
|
||||
icon_label.setToolTip(setting.description)
|
||||
|
||||
|
||||
# Add a horizontal layout for the setting
|
||||
layout = QHBoxLayout()
|
||||
# Add the label and the line edit to the layout
|
||||
layout.addItem(spacer)
|
||||
layout.addWidget(setting_label)
|
||||
layout.addWidget(line_edit)
|
||||
layout.addWidget(edit_widget)
|
||||
layout.addWidget(icon_label)
|
||||
layout.addStretch(1)
|
||||
# Add the layout to the vertical layout of the widget
|
||||
|
@ -84,4 +100,5 @@ class BaseSpectrometerView(ModuleView):
|
|||
|
||||
# Push all the settings to the top of the widget
|
||||
self._ui_form.verticalLayout.addStretch(1)
|
||||
|
||||
|
141
src/nqrduck_spectrometer/settings.py
Normal file
141
src/nqrduck_spectrometer/settings.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
import logging
|
||||
import ipaddress
|
||||
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Setting(QObject):
|
||||
"""A setting for the spectrometer is a value that is the same for all events in a pulse sequence.
|
||||
E.g. the number of averages or the number of points in a spectrum."""
|
||||
settings_changed = pyqtSignal()
|
||||
|
||||
def __init__(self, name, description) -> None:
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.description = description
|
||||
|
||||
@pyqtSlot(str)
|
||||
def on_value_changed(self, value):
|
||||
logger.debug("Setting %s changed to %s", self.name, value)
|
||||
self.value = value
|
||||
self.settings_changed.emit()
|
||||
|
||||
def get_setting(self):
|
||||
return float(self.value)
|
||||
|
||||
class FloatSetting(Setting):
|
||||
""" A setting that is a Float. """
|
||||
def __init__(self, name : str, default : float, description : str) -> None:
|
||||
super().__init__(name, description)
|
||||
self.value = default
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
try:
|
||||
self._value = float(value)
|
||||
except ValueError:
|
||||
raise ValueError("Value must be a float")
|
||||
self.settings_changed.emit()
|
||||
|
||||
|
||||
class IntSetting(Setting):
|
||||
""" A setting that is an Integer."""
|
||||
def __init__(self, name : str, default : int, description : str) -> None:
|
||||
super().__init__(name, description)
|
||||
self.value = default
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
try:
|
||||
self._value = int(value)
|
||||
except ValueError:
|
||||
raise ValueError("Value must be an int")
|
||||
self.settings_changed.emit()
|
||||
|
||||
class BooleanSetting(Setting):
|
||||
""" A setting that is a Boolean."""
|
||||
|
||||
def __init__(self, name : str, default : bool, description : str) -> None:
|
||||
super().__init__(name, description)
|
||||
self.value = default
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
try:
|
||||
self._value = bool(value)
|
||||
except ValueError:
|
||||
raise ValueError("Value must be a bool")
|
||||
self.settings_changed.emit()
|
||||
|
||||
class SelectionSetting(Setting):
|
||||
""" A setting that is a selection from a list of options."""
|
||||
def __init__(self, name : str, options : list, default : str, description : str) -> None:
|
||||
super().__init__(name, description)
|
||||
# Check if default is in options
|
||||
if default not in options:
|
||||
raise ValueError("Default value must be one of the options")
|
||||
|
||||
self.options = options
|
||||
self.value = default
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
if value in self.options:
|
||||
self._value = value
|
||||
else:
|
||||
raise ValueError("Value must be one of the options")
|
||||
self.settings_changed.emit()
|
||||
|
||||
class IPSetting(Setting):
|
||||
""" A setting that is an IP address."""
|
||||
def __init__(self, name : str, default : str, description : str) -> None:
|
||||
super().__init__(name, description)
|
||||
self.value = default
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
try:
|
||||
ipaddress.ip_address(value)
|
||||
self._value = value
|
||||
except ValueError:
|
||||
raise ValueError("Value must be a valid IP address")
|
||||
self.settings_changed.emit()
|
||||
|
||||
class StringSetting(Setting):
|
||||
""" A setting that is a string."""
|
||||
def __init__(self, name : str, default : str, description : str) -> None:
|
||||
super().__init__(name, description)
|
||||
self.value = default
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
try:
|
||||
self._value = str(value)
|
||||
except ValueError:
|
||||
raise ValueError("Value must be a string")
|
||||
|
||||
self.settings_changed.emit()
|
Loading…
Reference in a new issue