diff --git a/src/nqrduck_spectrometer/settings.py b/src/nqrduck_spectrometer/settings.py index 968ce07..eb0c26b 100644 --- a/src/nqrduck_spectrometer/settings.py +++ b/src/nqrduck_spectrometer/settings.py @@ -6,64 +6,78 @@ from PyQt6.QtGui import QValidator, QRegularExpressionValidator 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() + """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.""" - def __init__(self, name : str, description : str, default = None) -> None: - """ Create a new setting. - - Args: - name (str): The name of the setting. - description (str): A description of the setting. - """ - super().__init__() - self.name = name - self.description = description - if default is not None: - self.value = default + settings_changed = pyqtSignal() - # This can be overriden by subclasses - self.widget = self.get_widget() + def __init__(self, name: str, description: str, default=None) -> None: + """Create a new setting. - @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() + Args: + name (str): The name of the setting. + description (str): A description of the setting. + """ + super().__init__() + self.name = name + self.description = description + if default is not None: + self.value = default + + # This can be overriden by subclasses + self.widget = self.get_widget() + + @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) + + def get_widget(self): + """Return a widget for the setting. + The default widget is simply a QLineEdit. + This method can be overwritten by subclasses to return a different widget. + + Returns: + QLineEdit: A QLineEdit widget that can be used to change the setting. + + """ + widget = QLineEdit(str(self.value)) + widget.setMinimumWidth(100) + widget.editingFinished.connect( + lambda x=widget, s=self: s.on_value_changed(x.text()) + ) + return widget + + def update_widget_style(self): + """Update the style of the QLineEdit widget to indicate if the value is valid.""" + if ( + self.validator.validate(self.widget.text(), 0)[0] + == QValidator.State.Acceptable + ): + self.widget.setStyleSheet("QLineEdit { background-color: white; }") + elif ( + self.validator.validate(self.widget.text(), 0)[0] + == QValidator.State.Intermediate + ): + self.widget.setStyleSheet("QLineEdit { background-color: yellow; }") + else: + self.widget.setStyleSheet("QLineEdit { background-color: red; }") - def get_setting(self): - return float(self.value) - - def get_widget(self): - """Return a widget for the setting. - The default widget is simply a QLineEdit. - This method can be overwritten by subclasses to return a different widget. - - Returns: - QLineEdit: A QLineEdit widget that can be used to change the setting. - - """ - widget = QLineEdit(str(self.value)) - widget.setMinimumWidth(100) - widget.editingFinished.connect(lambda x=widget, s=self: s.on_value_changed(x.text())) - return widget - - def update_widget_style(self): - """ Update the style of the QLineEdit widget to indicate if the value is valid.""" - logger.debug("Updating widget style") - if self.validator.validate(self.widget.text(), 0)[0] == QValidator.State.Acceptable: - self.widget.setStyleSheet("QLineEdit { background-color: white; }") - elif self.validator.validate(self.widget.text(), 0)[0] == QValidator.State.Intermediate: - self.widget.setStyleSheet("QLineEdit { background-color: yellow; }") - else: - self.widget.setStyleSheet("QLineEdit { background-color: red; }") class FloatSetting(Setting): - """ A setting that is a Float. """ + """A setting that is a Float.""" + DEFAULT_LENGTH = 100 - def __init__(self, name : str, default : float, description : str, validator : QValidator = None) -> None: + + def __init__( + self, name: str, default: float, description: str, validator: QValidator = None + ) -> None: super().__init__(name, description, default) # If a validator is given, set it for the QLineEdit widget @@ -82,7 +96,7 @@ class FloatSetting(Setting): @property def value(self): return self._value - + @value.setter def value(self, value): try: @@ -97,9 +111,19 @@ class FloatSetting(Setting): self._value = float(value) self.settings_changed.emit() + class IntSetting(Setting): - """ A setting that is an Integer.""" - def __init__(self, name : str, default : int, description : str, validator : QValidator = None) -> None: + """A setting that is an Integer.""" + + def __init__( + self, + name: str, + default: int, + description: str, + validator: QValidator = None, + min_value=None, + max_value=None, + ) -> None: super().__init__(name, description, default) # If a validator is given, set it for the QLineEdit widget @@ -117,7 +141,7 @@ class IntSetting(Setting): @property def value(self): return self._value - + @value.setter def value(self, value): try: @@ -126,10 +150,11 @@ class IntSetting(Setting): 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: + """A setting that is a Boolean.""" + + def __init__(self, name: str, default: bool, description: str) -> None: super().__init__(name, description, default) # Overrides the default widget @@ -138,7 +163,7 @@ class BooleanSetting(Setting): @property def value(self): return self._value - + @value.setter def value(self, value): try: @@ -147,27 +172,32 @@ class BooleanSetting(Setting): raise ValueError("Value must be a bool") self.settings_changed.emit() - def get_widget(self): """Return a widget for the setting. This returns a QCheckBox widget. - + Returns: QCheckBox: A QCheckBox widget that can be used to change the setting. """ widget = QCheckBox() widget.setChecked(self.value) - widget.stateChanged.connect(lambda x=widget, s=self: s.on_value_changed(bool(x))) + widget.stateChanged.connect( + lambda x=widget, s=self: s.on_value_changed(bool(x)) + ) return widget + 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: + """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, default) # Check if default is in options if default not in options: raise ValueError("Default value must be one of the options") - + self.options = options # Overrides the default widget @@ -176,7 +206,7 @@ class SelectionSetting(Setting): @property def value(self): return self._value - + @value.setter def value(self, value): try: @@ -194,26 +224,30 @@ class SelectionSetting(Setting): def get_widget(self): """Return a widget for the setting. This returns a QComboBox widget. - + Returns: QComboBox: A QComboBox widget that can be used to change the setting. """ widget = QComboBox() widget.addItems(self.options) widget.setCurrentText(self.value) - widget.currentTextChanged.connect(lambda x=widget, s=self: s.on_value_changed(x)) + widget.currentTextChanged.connect( + lambda x=widget, s=self: s.on_value_changed(x) + ) return widget + class IPSetting(Setting): - """ A setting that is an IP address.""" - def __init__(self, name : str, default : str, description : str) -> None: + """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: @@ -223,20 +257,22 @@ class IPSetting(Setting): 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: + """A setting that is a string.""" + + def __init__(self, name: str, default: str, description: str) -> None: super().__init__(name, description, 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() \ No newline at end of file + + self.settings_changed.emit()