Source code for nexxT.interface.PropertyCollections

# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2020 ifm electronic gmbh
#
# THE PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
#

"""
This module defines the PropertyCollection interface class of the nexxT framework.
"""

from nexxT.Qt.QtCore import QObject, Signal, Slot

[docs] class PropertyHandler: """ .. note:: Import this class with :code:`from nexxT.interface import PropertyHandler`. This class represents a property definition for a specific type. The type handles loading/saving from and to .json configs as well as providing editor widgets for modifying the property in a model/view framework. It is an abstrct base class. For illustration, the implementation of the IntHandler is given here as an example: .. literalinclude:: ../../../nexxT/core/PropertyHandlers.py :pyobject: IntHandler .. note:: Usually, nexxT is using the wrapped C++ class instead of the python version. In python there are no differences between the wrapped C++ class and this python class. The C++ interface is defined in :cpp:class:`nexxT::PropertyHandler` """
[docs] def options(self): """ Returns the options set for this handler as a QVariantMap :return: a QVariantMap instance """ raise NotImplementedError()
[docs] def fromConfig(self, value): """ Converts the value read from the json file into the native python format :param value: a QVariant instance :return: the native value (also a QVariant) """ raise NotImplementedError()
[docs] def toConfig(self, value): """ Converts the native python format into a value suitable for json files. :param value: a QVariant instance (the native value) :return: the json value (also a QVariant) """ raise NotImplementedError()
[docs] def toViewValue(self, value): """ Converts the native python format into a value suitable for display in the Qt model/view framework. :param value: a QVariant instance (the native value) :return: a QVariant value (suitable value for display) """ raise NotImplementedError()
[docs] def validate(self, value): """ Returns a validated version of value. :param value: the value to be set :return: a validated version of value """ raise NotImplementedError()
[docs] def createEditor(self, parent): """ This is called in QStyledItemDelegate::createEditor; creates an editor widget instance. :param parent: a QWidget instance :return: a QWidget instance """ raise NotImplementedError()
[docs] def setEditorData(self, editor, value): """ This is called in QStyledItemDelegate::setEditorData; populates the editor widget with the actual data. :param editor: the editor widget as rezurned by createEditor :param value: the current property value, given as native python value :return: None """ raise NotImplementedError()
[docs] def getEditorData(self, editor): """ This is called in QStyledItemDelegate::setModelData; converts the value from the editor back to native python value. :param editor: the editor widget :return: a QVariant, the new native property value """ raise NotImplementedError()
[docs] class PropertyCollection(QObject): """ .. note:: Import this class with :code:`from nexxT.interface import PropertyCollection`. This class represents a collection of properties. These collections are organized in a tree, such that there are parent/child relations. This is a generic base class, which is implemented in the core package. Access to properties throug the methods below is thread safe. Properties are usually used in subclasses of :py:class:`nexxT.interface.Filters.Filter`. They are presented in the GUI as editable entities and the settings are saved to the configuration file. They are defined during filter constructor and onInit(...), they can be used during the whole filter lifecycle. There is also the possibility to connect a callback function to the :py:attr:`propertyChanged` signal. Note that properties are automatically deleted from the config file if they disappear (e.g., due to code changes, changed dynamic ports, etc.). Example:: class MyFilter(Filter): def __init__(self, env): super().__init__(False, False, env) pc = self.propertyCollection() pc.defineProperty("intProp", 1, "an unconstrained integer") pc.defineProperty("intPropMax", 1, "an max constrained integer", options=dict(max=10)) pc.defineProperty("intPropBounded", 1, "a bounded integer", options=dict(min=-4, max=10)) pc.defineProperty("floatProp", 1.0, "a floating point number", options=dict(min=-1e-4, max=10000)) pc.defineProperty("boolProp", True, "a boolean") # it is also possible to connect a callback pc.propertyChanged.connect(self.onPropertyChanged) def onInit(self): pc = self.propertyCollection() pc.defineProperty("strProp", "Hello World", "a string") pc.defineProperty("enumProp", "Hello", "a string", options=dict(enum=["Hello", "World"])) def onStart(self): # queries the current value of the property pc = self.propertyCollection() intProp = pc.getProperty("intProp") # ... def onPropertyChanged(self, pc, name): logger.info("Property '%s' changed to %s", name, repr(pc.getProperty(name))) In the above example, different editors will be created apropriate to the chosen values. For example, the enum property can be edited using a combo box while integer properties are edited with spin boxes. It is also possible to adapt this behaviour by passing custom propertyHandlers. This class is an abstract base class. .. note:: Usually, nexxT is using the wrapped C++ class instead of the python version. In python there are no differences between the wrapped C++ class and this python class. The C++ interface is defined in :cpp:class:`nexxT::PropertyCollection` """ propertyChanged = Signal(object, str) """ QT signal which is emitted after a property value of the collection has been changed by the user. :param pc: the PropertyCollection instance (i.e., the same as self.sender()) :param propName: the name of the property which has been changed. """
[docs] def defineProperty(self, name, defaultVal, helpstr, options=None, propertyHandler=None): """ Return the value of the given property, creating a new property if it doesn't exist. If it does exist, the definition must be consistent, otherwise an error is raised. Note that the parameters options and propertyHandler must not be present at the same time. That is because the options are already passed to the constructor of the propertyHandler. :param name: the name of the property :param defaultVal: the default value of the property. Note that this value will be used to determine the property's type. Currently supported types are string, int and float :param helpstr: a help string for the user (presented as a tool tip) :param options: a dict mapping string to qvariant (common options: 'min', 'max', 'enum') all properties support the option 'ignoreInconsistentOptions' (default: False). If this option is True, then nexxT allows that the options change over time. Even if present, the option type and its default values are not allowed to change. :param propertyHandler: a PropertyHandler instance, or None for automatic choice according to defaultVal :return: the current value of this property """ raise NotImplementedError()
[docs] def getProperty(self, name): """ return the property identified by name :param name: a string :return: the current property value """ raise NotImplementedError()
[docs] @Slot(str, object) def setProperty(self, name, value): """ Set the value of a named property. :param name: property name :param value: the value to be set :return: None """ raise NotImplementedError()
[docs] def evalpath(self, path): """ Evaluates the string path. If it is an absolute path it is unchanged, otherwise it is converted to an absolute path relative to the config file path. :param path: a string :return: absolute path as string """ raise NotImplementedError()