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)
[docs] 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)