Merge pull request #11 from nqrduck/validators

Validators
This commit is contained in:
Julia P 2024-03-14 17:07:49 +01:00 committed by GitHub
commit eade5e798f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 98 additions and 25 deletions

View file

@ -3,6 +3,8 @@ import json
import numpy as np import numpy as np
from decimal import Decimal from decimal import Decimal
from PyQt6.QtCore import pyqtSlot, pyqtSignal from PyQt6.QtCore import pyqtSlot, pyqtSignal
from PyQt6.QtGui import QValidator
from PyQt6.QtWidgets import QApplication
import nqrduck.helpers.signalprocessing as sp import nqrduck.helpers.signalprocessing as sp
from nqrduck_pulseprogrammer.view import OptionsDialog from nqrduck_pulseprogrammer.view import OptionsDialog
from nqrduck_spectrometer.pulsesequence import PulseSequence from nqrduck_spectrometer.pulsesequence import PulseSequence
@ -29,11 +31,13 @@ class MeasurementController(ModuleController):
Raises: Raises:
ValueError: If value cannot be converted to float.""" ValueError: If value cannot be converted to float."""
try:
logger.debug("Setting frequency to: %s MHz" % value) # Use validator
self.module.nqrduck_signal.emit("set_frequency", float(value) * 1e6) if self.module.model.validator_measurement_frequency.validate(value, 0) == QValidator.State.Acceptable:
except ValueError: self.module.model.measurement_frequency = float(value) * 1e6
self.set_averages_failure.emit() self.module.nqrduck_signal.emit("set_frequency", str(self.module.model.measurement_frequency))
self.toggle_start_button()
@pyqtSlot(str) @pyqtSlot(str)
def set_averages(self, value: str) -> None: def set_averages(self, value: str) -> None:
@ -43,7 +47,12 @@ class MeasurementController(ModuleController):
value (str): Number of averages. value (str): Number of averages.
""" """
logger.debug("Setting averages to: " + value) logger.debug("Setting averages to: " + value)
self.module.nqrduck_signal.emit("set_averages", value) #self.module.nqrduck_signal.emit("set_averages", value)
if self.module.model.validator_averages.validate(value, 0) == QValidator.State.Acceptable:
self.module.model.averages = int(value)
self.module.nqrduck_signal.emit("set_averages", str(self.module.model.averages))
self.toggle_start_button()
@pyqtSlot() @pyqtSlot()
def change_view_mode(self) -> None: def change_view_mode(self) -> None:
@ -57,11 +66,33 @@ class MeasurementController(ModuleController):
logger.debug("View mode changed to: " + self.module.model.view_mode) logger.debug("View mode changed to: " + self.module.model.view_mode)
def start_measurement(self) -> None: def start_measurement(self) -> None:
"""Emmit the start measurement signal.""" """Emit the start measurement signal."""
logger.debug("Start measurement clicked") logger.debug("Start measurement clicked")
self.module.view.measurement_dialog.show() self.module.view.measurement_dialog.show()
# Set the measurement parameters again in case the user switches spectrometer
self.module.nqrduck_signal.emit("set_frequency", str(self.module.model.measurement_frequency))
self.module.nqrduck_signal.emit("set_averages", str(self.module.model.averages))
QApplication.processEvents()
self.module.nqrduck_signal.emit("start_measurement", None) self.module.nqrduck_signal.emit("start_measurement", None)
def toggle_start_button(self) -> None:
"""Based on wether the Validators for frequency and averages are in an acceptable state, the start button is enabled or disabled."""
if (
self.module.model.validator_measurement_frequency.validate(
self.module.view._ui_form.frequencyEdit.text(), 0
)
== QValidator.State.Acceptable
and self.module.model.validator_averages.validate(
self.module.view._ui_form.averagesEdit.text(), 0
)
== QValidator.State.Acceptable
):
self.module.view._ui_form.buttonStart.setEnabled(True)
else:
self.module.view._ui_form.buttonStart.setEnabled(False)
def process_signals(self, key: str, value: object): def process_signals(self, key: str, value: object):
"""Process incoming signal from the nqrduck module. """Process incoming signal from the nqrduck module.

View file

@ -2,6 +2,7 @@ import logging
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
from nqrduck_spectrometer.measurement import Measurement from nqrduck_spectrometer.measurement import Measurement
from nqrduck.module.module_model import ModuleModel from nqrduck.module.module_model import ModuleModel
from nqrduck.helpers.validators import DuckFloatValidator, DuckIntValidator
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -16,12 +17,21 @@ class MeasurementModel(ModuleModel):
measurements_changed = pyqtSignal(list) measurements_changed = pyqtSignal(list)
view_mode_changed = pyqtSignal(str) view_mode_changed = pyqtSignal(str)
measurement_frequency_changed = pyqtSignal(float)
averages_changed = pyqtSignal(int)
def __init__(self, module) -> None: def __init__(self, module) -> None:
super().__init__(module) super().__init__(module)
self.view_mode = self.TIME_VIEW self.view_mode = self.TIME_VIEW
self.measurements = [] self.measurements = []
self._displayed_measurement = None self._displayed_measurement = None
self.validator_measurement_frequency = DuckFloatValidator(self, min_value=20.0, max_value=1000.0)
self.validator_averages = DuckIntValidator(self, min_value=1, max_value=1e6)
self.measurement_frequency = 100.0 # MHz
self.averages = 1
@property @property
def view_mode(self): def view_mode(self):
"""View mode of the measurement view. """View mode of the measurement view.
@ -59,3 +69,24 @@ class MeasurementModel(ModuleModel):
def displayed_measurement(self, value : Measurement): def displayed_measurement(self, value : Measurement):
self._displayed_measurement = value self._displayed_measurement = value
self.displayed_measurement_changed.emit(value) self.displayed_measurement_changed.emit(value)
@property
def measurement_frequency(self):
"""Measurement frequency."""
return self._measurement_frequency
@measurement_frequency.setter
def measurement_frequency(self, value : float):
# Validator is used to check if the value is in the correct range.
self._measurement_frequency = value
self.measurement_frequency_changed.emit(value)
@property
def averages(self):
"""Number of averages."""
return self._averages
@averages.setter
def averages(self, value : int):
self._averages = value
self.averages_changed.emit(value)

View file

@ -3,7 +3,7 @@ import numpy as np
from pathlib import Path from pathlib import Path
import matplotlib as mpl import matplotlib as mpl
from PyQt6.QtWidgets import QWidget, QDialog, QLabel, QVBoxLayout from PyQt6.QtWidgets import QWidget, QDialog, QLabel, QVBoxLayout
from PyQt6.QtGui import QMovie from PyQt6.QtGui import QValidator
from PyQt6.QtCore import pyqtSlot, Qt from PyQt6.QtCore import pyqtSlot, Qt
from nqrduck.module.module_view import ModuleView from nqrduck.module.module_view import ModuleView
from nqrduck.assets.icons import Logos from nqrduck.assets.icons import Logos
@ -54,19 +54,23 @@ class MeasurementView(ModuleView):
self._ui_form.buttonStart.clicked.connect(self.on_measurement_start_button_clicked) self._ui_form.buttonStart.clicked.connect(self.on_measurement_start_button_clicked)
self._ui_form.fftButton.clicked.connect(self.module.controller.change_view_mode) self._ui_form.fftButton.clicked.connect(self.module.controller.change_view_mode)
self._ui_form.frequencyEdit.editingFinished.connect(lambda: self.on_editing_finished(self._ui_form.frequencyEdit.text())) # Measurement settings controller
self._ui_form.averagesEdit.editingFinished.connect(lambda: self.on_editing_finished(self._ui_form.averagesEdit.text())) self._ui_form.frequencyEdit.textChanged.connect(lambda: self.module.controller.set_frequency(self._ui_form.frequencyEdit.text()))
self._ui_form.averagesEdit.textChanged.connect(lambda: self.module.controller.set_averages(self._ui_form.averagesEdit.text()))
# Update fields
self._ui_form.frequencyEdit.textChanged.connect(lambda: self.update_input_widgets(self._ui_form.frequencyEdit, self.module.model.validator_measurement_frequency ))
self._ui_form.averagesEdit.textChanged.connect(lambda: self.update_input_widgets(self._ui_form.averagesEdit, self.module.model.validator_averages))
self.module.controller.set_frequency_failure.connect(self.on_set_frequency_failure) self.module.controller.set_frequency_failure.connect(self.on_set_frequency_failure)
self.module.controller.set_averages_failure.connect(self.on_set_averages_failure) self.module.controller.set_averages_failure.connect(self.on_set_averages_failure)
self._ui_form.apodizationButton.clicked.connect(self.module.controller.show_apodization_dialog) self._ui_form.apodizationButton.clicked.connect(self.module.controller.show_apodization_dialog)
# Call validator for buttonStart
# Add logos # Add logos
self._ui_form.buttonStart.setIcon(Logos.Play_16x16()) self._ui_form.buttonStart.setIcon(Logos.Play_16x16())
self._ui_form.buttonStart.setIconSize(self._ui_form.buttonStart.size()) self._ui_form.buttonStart.setIconSize(self._ui_form.buttonStart.size())
self._ui_form.buttonStart.setEnabled(False)
self._ui_form.exportButton.setIcon(Logos.Save16x16()) self._ui_form.exportButton.setIcon(Logos.Save16x16())
self._ui_form.exportButton.setIconSize(self._ui_form.exportButton.size()) self._ui_form.exportButton.setIconSize(self._ui_form.exportButton.size())
@ -150,19 +154,6 @@ class MeasurementView(ModuleView):
logger.debug("Measurement start button clicked.") logger.debug("Measurement start button clicked.")
self.module.controller.start_measurement() self.module.controller.start_measurement()
@pyqtSlot(str)
def on_editing_finished(self, value : str) -> None:
"""Slot for when the editing of either the frequencyEdit or averagesEdit is finished.
Args:
value (str): The value of the line edit."""
logger.debug("Editing finished.")
self.sender().setStyleSheet("")
if self.sender() == self._ui_form.frequencyEdit:
self.module.controller.set_frequency(value)
elif self.sender() == self._ui_form.averagesEdit:
self.module.controller.set_averages(value)
@pyqtSlot() @pyqtSlot()
def on_set_frequency_failure(self) -> None: def on_set_frequency_failure(self) -> None:
"""Slot for when the set frequency signal fails.""" """Slot for when the set frequency signal fails."""
@ -195,6 +186,26 @@ class MeasurementView(ModuleView):
if file_name: if file_name:
self.module.controller.load_measurement(file_name) self.module.controller.load_measurement(file_name)
@pyqtSlot()
def update_input_widgets(self, widget, validator) -> None:
"""Update the style of the QLineEdit widget to indicate if the value is valid.
Args:
widget (QLineEdit): The widget to update.
validator (QValidator): The validator to use for the widget."""
if (
validator.validate(widget.text(), 0)
== QValidator.State.Acceptable
):
widget.setStyleSheet("QLineEdit { background-color: white; }")
elif (
validator.validate(widget.text(), 0)
== QValidator.State.Intermediate
):
widget.setStyleSheet("QLineEdit { background-color: yellow; }")
else:
widget.setStyleSheet("QLineEdit { background-color: red; }")
class MeasurementDialog(QDialog): class MeasurementDialog(QDialog):
""" This Dialog is shown when the measurement is started and therefore blocks the main window. """ This Dialog is shown when the measurement is started and therefore blocks the main window.