mirror of
https://github.com/nqrduck/nqrduck-pulseprogrammer.git
synced 2024-12-22 15:47:47 +00:00
Merge pull request #12 from nqrduck/formbuilder-and-function-optimization
Formbuilder and function optimization
This commit is contained in:
commit
aee28b3d7a
4 changed files with 75 additions and 313 deletions
|
@ -1,5 +1,7 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### Version 0.0.3 (26-04-2024)
|
||||||
|
- Switched to new formbuilder provided by the nqrduck core
|
||||||
### Version 0.0.2 (18-04-2024)
|
### Version 0.0.2 (18-04-2024)
|
||||||
- Automatic deployment to PyPI
|
- Automatic deployment to PyPI
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "nqrduck-pulseprogrammer"
|
name = "nqrduck-pulseprogrammer"
|
||||||
version = "0.0.2"
|
version = "0.0.3"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="jupfi", email="support@nqrduck.cool" },
|
{ name="jupfi", email="support@nqrduck.cool" },
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import logging
|
import logging
|
||||||
from decimal import Decimal
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from PyQt6.QtCore import pyqtSignal
|
from PyQt6.QtCore import pyqtSignal
|
||||||
from nqrduck.module.module_model import ModuleModel
|
from nqrduck.module.module_model import ModuleModel
|
||||||
|
@ -18,15 +17,15 @@ class PulseProgrammerModel(ModuleModel):
|
||||||
self.pulse_parameter_options = OrderedDict()
|
self.pulse_parameter_options = OrderedDict()
|
||||||
self.pulse_sequence = PulseSequence("Untitled pulse sequence")
|
self.pulse_sequence = PulseSequence("Untitled pulse sequence")
|
||||||
|
|
||||||
def add_event(self, event_name: str, duration: Decimal = 20):
|
def add_event(self, event_name: str, duration: float = 20):
|
||||||
"""Add a new event to the current pulse sequence.
|
"""Add a new event to the current pulse sequence.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
event_name (str): A human-readable name for the event
|
event_name (str): A human-readable name for the event
|
||||||
duration (Decimal): The duration of the event in µs. Defaults to 20.
|
duration (float): The duration of the event in µs. Defaults to 20.
|
||||||
"""
|
"""
|
||||||
self.pulse_sequence.events.append(
|
self.pulse_sequence.events.append(
|
||||||
PulseSequence.Event(event_name, "%.16gu" % duration)
|
PulseSequence.Event(event_name, "%.16gu" % float(duration))
|
||||||
)
|
)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Creating event %s with object id %s",
|
"Creating event %s with object id %s",
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import functools
|
import functools
|
||||||
from collections import OrderedDict
|
|
||||||
from decimal import Decimal
|
|
||||||
from PyQt6.QtGui import QValidator
|
from PyQt6.QtGui import QValidator
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QMessageBox,
|
|
||||||
QGroupBox,
|
|
||||||
QFormLayout,
|
QFormLayout,
|
||||||
QTableWidget,
|
QTableWidget,
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
|
@ -16,7 +12,6 @@ from PyQt6.QtWidgets import (
|
||||||
QLineEdit,
|
QLineEdit,
|
||||||
QDialogButtonBox,
|
QDialogButtonBox,
|
||||||
QWidget,
|
QWidget,
|
||||||
QCheckBox,
|
|
||||||
QToolButton,
|
QToolButton,
|
||||||
QFileDialog,
|
QFileDialog,
|
||||||
QSizePolicy,
|
QSizePolicy,
|
||||||
|
@ -30,6 +25,14 @@ from nqrduck_spectrometer.pulseparameters import (
|
||||||
NumericOption,
|
NumericOption,
|
||||||
FunctionOption,
|
FunctionOption,
|
||||||
)
|
)
|
||||||
|
from nqrduck.helpers.formbuilder import (
|
||||||
|
DuckFormBuilder,
|
||||||
|
DuckFormFunctionSelectionField,
|
||||||
|
DuckFormCheckboxField,
|
||||||
|
DuckFormDropdownField,
|
||||||
|
DuckFormFloatField,
|
||||||
|
DuckFormIntField,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -175,7 +178,7 @@ class PulseProgrammerView(ModuleView):
|
||||||
logger.debug("Adding event to pulseprogrammer view: %s", event.name)
|
logger.debug("Adding event to pulseprogrammer view: %s", event.name)
|
||||||
# Create a label for the event
|
# Create a label for the event
|
||||||
event_label = QLabel(
|
event_label = QLabel(
|
||||||
"%s : %.16g µs" % (event.name, (event.duration * Decimal(1e6)))
|
"%s : %.16g µs" % (event.name, (event.duration * 1e6))
|
||||||
)
|
)
|
||||||
event_layout.addWidget(event_label)
|
event_layout.addWidget(event_label)
|
||||||
|
|
||||||
|
@ -260,19 +263,65 @@ class PulseProgrammerView(ModuleView):
|
||||||
"""This method is called whenever a button in the pulse table is clicked. It opens a dialog to set the options for the parameter."""
|
"""This method is called whenever a button in the pulse table is clicked. It opens a dialog to set the options for the parameter."""
|
||||||
logger.debug("Button for event %s and parameter %s clicked", event, parameter)
|
logger.debug("Button for event %s and parameter %s clicked", event, parameter)
|
||||||
# Create a QDialog to set the options for the parameter.
|
# Create a QDialog to set the options for the parameter.
|
||||||
dialog = OptionsDialog(event, parameter, self)
|
description = f"Set options for {parameter}"
|
||||||
|
dialog = DuckFormBuilder(parameter, description=description, parent=self)
|
||||||
|
|
||||||
|
# Adding fields for the options
|
||||||
|
form_options = []
|
||||||
|
for option in event.parameters[parameter].options:
|
||||||
|
if isinstance(option, BooleanOption):
|
||||||
|
boolean_form = DuckFormCheckboxField(
|
||||||
|
option.name, tooltip=None, default=option.value
|
||||||
|
)
|
||||||
|
dialog.add_field(boolean_form)
|
||||||
|
form_options.append(option)
|
||||||
|
elif isinstance(option, NumericOption):
|
||||||
|
# We only show the slider if both min and max values are set
|
||||||
|
if option.min_value is not None and option.max_value is not None:
|
||||||
|
slider = True
|
||||||
|
else:
|
||||||
|
slider = False
|
||||||
|
|
||||||
|
numeric_field = DuckFormFloatField(
|
||||||
|
option.name,
|
||||||
|
tooltip=None,
|
||||||
|
default=option.value,
|
||||||
|
min_value=option.min_value,
|
||||||
|
max_value=option.max_value,
|
||||||
|
slider=slider,
|
||||||
|
)
|
||||||
|
|
||||||
|
dialog.add_field(numeric_field)
|
||||||
|
form_options.append(option)
|
||||||
|
elif isinstance(option, FunctionOption):
|
||||||
|
logger.debug(f"Functions: {option.functions}")
|
||||||
|
|
||||||
|
# When loading a pulse sequence, the instance of the objects will be different
|
||||||
|
# Therefore we need to operate on the classes
|
||||||
|
for function in option.functions:
|
||||||
|
if function.__class__.__name__ == option.value.__class__.__name__:
|
||||||
|
default_function = function
|
||||||
|
|
||||||
|
index = option.functions.index(default_function)
|
||||||
|
|
||||||
|
function_field = DuckFormFunctionSelectionField(
|
||||||
|
option.name,
|
||||||
|
tooltip=None,
|
||||||
|
functions=option.functions,
|
||||||
|
duration=event.duration,
|
||||||
|
default_function=index,
|
||||||
|
)
|
||||||
|
dialog.add_field(function_field)
|
||||||
|
form_options.append(option)
|
||||||
|
|
||||||
result = dialog.exec()
|
result = dialog.exec()
|
||||||
|
|
||||||
|
options = event.parameters[parameter].options
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
for option, function in dialog.return_functions.items():
|
values = dialog.get_values()
|
||||||
logger.debug(
|
for i, value in enumerate(values):
|
||||||
"Setting option %s of parameter %s in event %s to %s",
|
options[i].value = value
|
||||||
option,
|
|
||||||
parameter,
|
|
||||||
event,
|
|
||||||
function(),
|
|
||||||
)
|
|
||||||
option.set_value(function())
|
|
||||||
|
|
||||||
self.set_parameter_icons()
|
self.set_parameter_icons()
|
||||||
|
|
||||||
|
@ -382,7 +431,7 @@ class EventOptionsWidget(QWidget):
|
||||||
duration_label = QLabel("Duration:")
|
duration_label = QLabel("Duration:")
|
||||||
duration_lineedit = QLineEdit()
|
duration_lineedit = QLineEdit()
|
||||||
unit_label = QLabel("µs")
|
unit_label = QLabel("µs")
|
||||||
duration_lineedit.setText("%.16g" % (self.event.duration * Decimal(1e6)))
|
duration_lineedit.setText("%.16g" % (self.event.duration * 1e6))
|
||||||
duration_layout.addWidget(duration_label)
|
duration_layout.addWidget(duration_label)
|
||||||
duration_layout.addWidget(duration_lineedit)
|
duration_layout.addWidget(duration_lineedit)
|
||||||
duration_layout.addWidget(unit_label)
|
duration_layout.addWidget(unit_label)
|
||||||
|
@ -441,294 +490,6 @@ class EventOptionsWidget(QWidget):
|
||||||
self.move_event_right.emit(self.event.name)
|
self.move_event_right.emit(self.event.name)
|
||||||
|
|
||||||
|
|
||||||
class OptionsDialog(QDialog):
|
|
||||||
"""This dialog is created whenever the edit button for a pulse option is clicked.
|
|
||||||
It allows the user to change the options for the pulse parameter and creates the dialog in accordance to what can be set.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, event, parameter, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
self.setWindowTitle("Options")
|
|
||||||
|
|
||||||
self.layout = QVBoxLayout(self)
|
|
||||||
|
|
||||||
numeric_layout = QFormLayout()
|
|
||||||
numeric_layout.setHorizontalSpacing(30)
|
|
||||||
|
|
||||||
self.label = QLabel("Change options for the pulse parameter: %s" % parameter)
|
|
||||||
self.layout.addWidget(self.label)
|
|
||||||
|
|
||||||
self.layout.addLayout(numeric_layout)
|
|
||||||
|
|
||||||
# If the parameter is a string, we first need to get the parameter object from the according event
|
|
||||||
if isinstance(parameter, str):
|
|
||||||
parameter = event.parameters[parameter]
|
|
||||||
|
|
||||||
options = parameter.get_options()
|
|
||||||
|
|
||||||
# Based on these options we will now create our selection widget
|
|
||||||
self.return_functions = OrderedDict()
|
|
||||||
|
|
||||||
# If the options are a list , we will create a QComboBox
|
|
||||||
for option in options:
|
|
||||||
if option == list:
|
|
||||||
pass
|
|
||||||
# If the options are boolean, we will create a QCheckBox
|
|
||||||
elif isinstance(option, BooleanOption):
|
|
||||||
check_box = QCheckBox()
|
|
||||||
|
|
||||||
def checkbox_result():
|
|
||||||
return check_box.isChecked()
|
|
||||||
|
|
||||||
check_box.setChecked(option.value)
|
|
||||||
self.layout.addWidget(check_box)
|
|
||||||
self.return_functions[option] = checkbox_result
|
|
||||||
|
|
||||||
# If the options are a float/int we will create a QSpinBox
|
|
||||||
elif isinstance(option, NumericOption):
|
|
||||||
numeric_label = QLabel(option.name)
|
|
||||||
numeric_lineedit = QLineEdit(str(option.value))
|
|
||||||
numeric_lineedit.setMaximumWidth(300)
|
|
||||||
numeric_layout.addRow(numeric_label, numeric_lineedit)
|
|
||||||
|
|
||||||
self.return_functions[option] = numeric_lineedit.text
|
|
||||||
|
|
||||||
# If the options are a string we will create a QLineEdit
|
|
||||||
elif option == str:
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif isinstance(option, FunctionOption):
|
|
||||||
function_option = FunctionOptionWidget(option, event, parent)
|
|
||||||
self.layout.addWidget(function_option)
|
|
||||||
|
|
||||||
logger.debug("Return functions are: %s" % self.return_functions.items())
|
|
||||||
|
|
||||||
self.buttons = QDialogButtonBox(
|
|
||||||
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel,
|
|
||||||
self,
|
|
||||||
)
|
|
||||||
self.buttons.accepted.connect(self.accept)
|
|
||||||
self.buttons.rejected.connect(self.reject)
|
|
||||||
|
|
||||||
self.layout.addWidget(self.buttons)
|
|
||||||
|
|
||||||
|
|
||||||
class FunctionOptionWidget(QWidget):
|
|
||||||
"""This class is a widget that can be used to set the options for a pulse parameter.
|
|
||||||
It plots the given function in time and frequency domain.
|
|
||||||
One can also select the function from a list of functions represented as buttons.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, function_option, event, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
self.function_option = function_option
|
|
||||||
self.event = event
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
inner_layout = QHBoxLayout()
|
|
||||||
for function in function_option.functions:
|
|
||||||
button = QPushButton(function.name)
|
|
||||||
button.clicked.connect(
|
|
||||||
functools.partial(self.on_functionbutton_clicked, function=function)
|
|
||||||
)
|
|
||||||
inner_layout.addWidget(button)
|
|
||||||
|
|
||||||
layout.addLayout(inner_layout)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
# Add Advanced settings button
|
|
||||||
self.advanced_settings_button = QPushButton("Show Advanced settings")
|
|
||||||
self.advanced_settings_button.clicked.connect(
|
|
||||||
self.on_advanced_settings_button_clicked
|
|
||||||
)
|
|
||||||
layout.addWidget(self.advanced_settings_button)
|
|
||||||
|
|
||||||
# Add advanced settings widget
|
|
||||||
self.advanced_settings = QGroupBox("Advanced Settings")
|
|
||||||
self.advanced_settings.setHidden(True)
|
|
||||||
self.advanced_settings_layout = QFormLayout()
|
|
||||||
self.advanced_settings.setLayout(self.advanced_settings_layout)
|
|
||||||
layout.addWidget(self.advanced_settings)
|
|
||||||
|
|
||||||
# Add the advanced settings
|
|
||||||
# Advanced settings are resolution, start_x = -1, end_x and the expr of the function_option.value
|
|
||||||
resolution_layout = QHBoxLayout()
|
|
||||||
resolution_label = QLabel("Resolution:")
|
|
||||||
self.resolution_lineedit = QLineEdit(str(function_option.value.resolution))
|
|
||||||
resolution_layout.addWidget(resolution_label)
|
|
||||||
resolution_layout.addWidget(self.resolution_lineedit)
|
|
||||||
resolution_layout.addStretch(1)
|
|
||||||
self.advanced_settings_layout.addRow(resolution_label, resolution_layout)
|
|
||||||
|
|
||||||
start_x_layout = QHBoxLayout()
|
|
||||||
start_x_label = QLabel("Start x:")
|
|
||||||
self.start_x_lineedit = QLineEdit(str(function_option.value.start_x))
|
|
||||||
start_x_layout.addWidget(start_x_label)
|
|
||||||
start_x_layout.addWidget(self.start_x_lineedit)
|
|
||||||
start_x_layout.addStretch(1)
|
|
||||||
self.advanced_settings_layout.addRow(start_x_label, start_x_layout)
|
|
||||||
|
|
||||||
end_x_layout = QHBoxLayout()
|
|
||||||
end_x_label = QLabel("End x:")
|
|
||||||
self.end_x_lineedit = QLineEdit(str(function_option.value.end_x))
|
|
||||||
end_x_layout.addWidget(end_x_label)
|
|
||||||
end_x_layout.addWidget(self.end_x_lineedit)
|
|
||||||
end_x_layout.addStretch(1)
|
|
||||||
self.advanced_settings_layout.addRow(end_x_label, end_x_layout)
|
|
||||||
|
|
||||||
expr_layout = QHBoxLayout()
|
|
||||||
expr_label = QLabel("Expression:")
|
|
||||||
self.expr_lineedit = QLineEdit(str(function_option.value.expr))
|
|
||||||
expr_layout.addWidget(expr_label)
|
|
||||||
expr_layout.addWidget(self.expr_lineedit)
|
|
||||||
expr_layout.addStretch(1)
|
|
||||||
self.advanced_settings_layout.addRow(expr_label, expr_layout)
|
|
||||||
|
|
||||||
# Add buttton for replotting of the active function with the new parameters
|
|
||||||
self.replot_button = QPushButton("Replot")
|
|
||||||
self.replot_button.clicked.connect(self.on_replot_button_clicked)
|
|
||||||
layout.addWidget(self.replot_button)
|
|
||||||
|
|
||||||
# Display the active function
|
|
||||||
self.load_active_function()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_replot_button_clicked(self) -> None:
|
|
||||||
"""This function is called when the replot button is clicked.
|
|
||||||
It will update the parameters of the function and replots the function.
|
|
||||||
"""
|
|
||||||
logger.debug("Replot button clicked")
|
|
||||||
# Update the resolution, start_x, end_x and expr lineedits
|
|
||||||
self.function_option.value.resolution = self.resolution_lineedit.text()
|
|
||||||
self.function_option.value.start_x = self.start_x_lineedit.text()
|
|
||||||
self.function_option.value.end_x = self.end_x_lineedit.text()
|
|
||||||
try:
|
|
||||||
self.function_option.value.expr = self.expr_lineedit.text()
|
|
||||||
except SyntaxError:
|
|
||||||
logger.debug("Invalid expression: %s", self.expr_lineedit.text())
|
|
||||||
self.expr_lineedit.setText(str(self.function_option.value.expr))
|
|
||||||
# Create message box that tells the user that the expression is invalid
|
|
||||||
self.create_message_box(
|
|
||||||
"Invalid expression",
|
|
||||||
"The expression you entered is invalid. Please enter a valid expression.",
|
|
||||||
)
|
|
||||||
|
|
||||||
self.delete_active_function()
|
|
||||||
self.load_active_function()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_advanced_settings_button_clicked(self) -> None:
|
|
||||||
"""This function is called when the advanced settings button is clicked.
|
|
||||||
It will show or hide the advanced settings.
|
|
||||||
"""
|
|
||||||
if self.advanced_settings.isHidden():
|
|
||||||
self.advanced_settings.setHidden(False)
|
|
||||||
self.advanced_settings_button.setText("Hide Advanced Settings")
|
|
||||||
else:
|
|
||||||
self.advanced_settings.setHidden(True)
|
|
||||||
self.advanced_settings_button.setText("Show Advanced Settings")
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_functionbutton_clicked(self, function) -> None:
|
|
||||||
"""This function is called when a function button is clicked.
|
|
||||||
It will update the function_option.value to the function that was clicked.
|
|
||||||
"""
|
|
||||||
logger.debug("Button for function %s clicked", function.name)
|
|
||||||
self.function_option.set_value(function)
|
|
||||||
self.delete_active_function()
|
|
||||||
self.load_active_function()
|
|
||||||
|
|
||||||
def delete_active_function(self) -> None:
|
|
||||||
"""This function is called when the active function is deleted.
|
|
||||||
It will remove the active function from the layout.
|
|
||||||
"""
|
|
||||||
# Remove the plotter with object name "plotter" from the layout
|
|
||||||
for i in reversed(range(self.layout().count())):
|
|
||||||
item = self.layout().itemAt(i)
|
|
||||||
if item.widget() and item.widget().objectName() == "active_function":
|
|
||||||
item.widget().deleteLater()
|
|
||||||
break
|
|
||||||
|
|
||||||
def load_active_function(self) -> None:
|
|
||||||
"""This function is called when the active function is loaded.
|
|
||||||
It will add the active function to the layout.
|
|
||||||
"""
|
|
||||||
# New QWidget for the active function
|
|
||||||
active_function_Widget = QWidget()
|
|
||||||
active_function_Widget.setObjectName("active_function")
|
|
||||||
|
|
||||||
function_layout = QVBoxLayout()
|
|
||||||
|
|
||||||
plot_layout = QHBoxLayout()
|
|
||||||
|
|
||||||
# Add plot for time domain
|
|
||||||
time_domain_layout = QVBoxLayout()
|
|
||||||
time_domain_label = QLabel("Time domain:")
|
|
||||||
time_domain_layout.addWidget(time_domain_label)
|
|
||||||
plot = self.function_option.value.time_domain_plot(self.event.duration)
|
|
||||||
time_domain_layout.addWidget(plot)
|
|
||||||
plot_layout.addLayout(time_domain_layout)
|
|
||||||
|
|
||||||
# Add plot for frequency domain
|
|
||||||
frequency_domain_layout = QVBoxLayout()
|
|
||||||
frequency_domain_label = QLabel("Frequency domain:")
|
|
||||||
frequency_domain_layout.addWidget(frequency_domain_label)
|
|
||||||
plot = self.function_option.value.frequency_domain_plot(self.event.duration)
|
|
||||||
frequency_domain_layout.addWidget(plot)
|
|
||||||
plot_layout.addLayout(frequency_domain_layout)
|
|
||||||
|
|
||||||
function_layout.addLayout(plot_layout)
|
|
||||||
|
|
||||||
parameter_layout = QFormLayout()
|
|
||||||
parameter_label = QLabel("Parameters:")
|
|
||||||
parameter_layout.addRow(parameter_label)
|
|
||||||
for parameter in self.function_option.value.parameters:
|
|
||||||
parameter_label = QLabel(parameter.name)
|
|
||||||
parameter_lineedit = QLineEdit(str(parameter.value))
|
|
||||||
# Add the parameter_lineedit editingFinished signal to the paramter.set_value slot
|
|
||||||
parameter_lineedit.editingFinished.connect(
|
|
||||||
lambda: parameter.set_value(parameter_lineedit.text())
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create a QHBoxLayout
|
|
||||||
hbox = QHBoxLayout()
|
|
||||||
|
|
||||||
# Add your QLineEdit and a stretch to the QHBoxLayout
|
|
||||||
hbox.addWidget(parameter_lineedit)
|
|
||||||
hbox.addStretch(1)
|
|
||||||
|
|
||||||
# Use addRow() method to add label and the QHBoxLayout next to each other
|
|
||||||
parameter_layout.addRow(parameter_label, hbox)
|
|
||||||
|
|
||||||
function_layout.addLayout(parameter_layout)
|
|
||||||
function_layout.addStretch(1)
|
|
||||||
active_function_Widget.setLayout(function_layout)
|
|
||||||
self.layout().addWidget(active_function_Widget)
|
|
||||||
|
|
||||||
# Update the resolution, start_x, end_x and expr lineedits
|
|
||||||
self.resolution_lineedit.setText(str(self.function_option.value.resolution))
|
|
||||||
self.start_x_lineedit.setText(str(self.function_option.value.start_x))
|
|
||||||
self.end_x_lineedit.setText(str(self.function_option.value.end_x))
|
|
||||||
self.expr_lineedit.setText(str(self.function_option.value.expr))
|
|
||||||
|
|
||||||
def create_message_box(self, message: str, information: str) -> None:
|
|
||||||
"""Creates a message box with the given message and information and shows it.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
message (str): The message to be shown in the message box
|
|
||||||
information (str): The information to be shown in the message box
|
|
||||||
"""
|
|
||||||
msg = QMessageBox(parent=self.parent)
|
|
||||||
msg.setIcon(QMessageBox.Icon.Warning)
|
|
||||||
msg.setText(message)
|
|
||||||
msg.setInformativeText(information)
|
|
||||||
msg.setWindowTitle("Warning")
|
|
||||||
msg.exec()
|
|
||||||
|
|
||||||
|
|
||||||
class AddEventDialog(QDialog):
|
class AddEventDialog(QDialog):
|
||||||
"""This dialog is created whenever a new event is added to the pulse sequence. It allows the user to enter a name for the event."""
|
"""This dialog is created whenever a new event is added to the pulse sequence. It allows the user to enter a name for the event."""
|
||||||
|
|
||||||
|
@ -782,13 +543,13 @@ class AddEventDialog(QDialog):
|
||||||
"""
|
"""
|
||||||
return self.name_input.text()
|
return self.name_input.text()
|
||||||
|
|
||||||
def get_duration(self) -> Decimal:
|
def get_duration(self) -> float:
|
||||||
"""Returns the duration entered by the user, or a fallback value."
|
"""Returns the duration entered by the user, or a fallback value."
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Decimal: The duration value provided by the user, or 20
|
float: The duration value provided by the user, or 20
|
||||||
"""
|
"""
|
||||||
return Decimal(self.duration_lineedit.text() or 20)
|
return self.duration_lineedit.text() or 20
|
||||||
|
|
||||||
def check_input(self) -> None:
|
def check_input(self) -> None:
|
||||||
"""Checks if the name and duration entered by the user is valid. If it is, the dialog is accepted. If not, the user is informed of the error."""
|
"""Checks if the name and duration entered by the user is valid. If it is, the dialog is accepted. If not, the user is informed of the error."""
|
||||||
|
|
Loading…
Reference in a new issue