Source code for qudi.util.widgets.parameter_editor
# -*- coding: utf-8 -*-
"""
Copyright (c) 2021, the qudi developers. See the AUTHORS.md file at the top-level directory of this
distribution and on <https://github.com/Ulm-IQO/qudi-core/>
This file is part of qudi.
Qudi is free software: you can redistribute it and/or modify it under the terms of
the GNU Lesser General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
Qudi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with qudi.
If not, see <https://www.gnu.org/licenses/>.
"""
__all__ = ['ParameterEditor', 'ParameterEditorDialog']
import inspect
from typing import Any, Optional, Dict, Mapping, Callable
from PySide2 import QtCore, QtWidgets
from qudi.util.parameters import ParameterWidgetMapper
[docs]
class ParameterEditor(QtWidgets.QWidget):
""" Dynamically created editor widget for callable parameters.
For best results use default values and simple type annotations in the callable to create the
editor for.
"""
INVALID = object()
[docs]
def __init__(self, *args, func: Callable, values: Optional[Mapping[str, Any]] = None, **kwargs):
super().__init__(*args, **kwargs)
if values is None:
values = dict()
self.parameter_editors = dict()
layout = QtWidgets.QGridLayout()
parameters = inspect.signature(func).parameters
for row, (name, param) in enumerate(parameters.items()):
label = QtWidgets.QLabel(f'{name}:')
label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
editor = ParameterWidgetMapper.widget_for_parameter(param)
if editor is None:
editor = QtWidgets.QLabel('Unknown argument type!')
editor.setAlignment(QtCore.Qt.AlignCenter)
else:
editor = editor()
# Attempt to set default value
if not ((param.default is inspect.Parameter.empty) and (name not in values)):
try:
init_value = values[name]
except KeyError:
init_value = param.default
try:
editor.setValue(init_value)
except AttributeError:
try:
editor.setChecked(init_value)
except AttributeError:
try:
editor.setText(init_value)
except AttributeError:
pass
layout.addWidget(label, row, 0)
layout.addWidget(editor, row, 1)
self.parameter_editors[name] = editor
self.setLayout(layout)
def get_parameter_values(self) -> Dict[str, Any]:
""" Returns the current parameter values entered into the editor """
values = dict()
for name, editor in self.parameter_editors.items():
if isinstance(editor, QtWidgets.QLabel):
values[name] = self.INVALID
else:
try:
values[name] = editor.value()
except AttributeError:
try:
values[name] = editor.isChecked()
except AttributeError:
try:
values[name] = editor.text()
except AttributeError:
pass
return values
[docs]
class ParameterEditorDialog(QtWidgets.QDialog):
""" QDialog containing a ParameterEditor widget and OK, Cancel and Apply buttons.
"""
[docs]
def __init__(self, *args, func: Callable, values: Optional[Mapping[str, Any]] = None, **kwargs):
super().__init__(*args, **kwargs)
self.parameter_editor = ParameterEditor(func=func, values=values)
self.scroll_area = QtWidgets.QScrollArea()
self.scroll_area.setWidget(self.parameter_editor)
self.button_box = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.Ok |
QtWidgets.QDialogButtonBox.Cancel |
QtWidgets.QDialogButtonBox.Apply,
orientation=QtCore.Qt.Horizontal
)
self.ok_button = self.button_box.button(QtWidgets.QDialogButtonBox.Ok)
self.cancel_button = self.button_box.button(QtWidgets.QDialogButtonBox.Cancel)
self.apply_button = self.button_box.button(QtWidgets.QDialogButtonBox.Apply)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.scroll_area)
layout.addWidget(self.button_box)
self.setLayout(layout)
# Connect signals
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)