nexxT.interface package
This __init__.py generates shortcuts for exported classes
- class nexxT.interface.DataSample(content, datatype, timestamp)[source]
Bases:
objectNote
Import this class with
from nexxT.interface import DataSample.This class is used for storing a data sample of the nexxT framework. For most generic usage, a QByteArray is used for the storage. This means that deserialization has to be performed on every usage and data generators need to serialize the data. Assumes that serializing / deserializing are efficient operations.
DataSample instances additionally have a type, which is a string and it should uniquely define the serialization method. Last but not least, an integer timestamp is stored for all DataSample instances.
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
nexxT::DataSample- TIMESTAMP_RES = 1e-06
the resolution of the timestamps
- __init__(content, datatype, timestamp)[source]
Create a new data sample instance.
- Parameters:
content – A QByteArray instance containing the (serialized) content
datatype – A string instance which uniquely defines the serialized content
timestamp – An integer representing the sample’s time stamp [µs]
- static copy(src)[source]
Create a copy of this DataSample instance
- Parameters:
src – the instance to be copied
- Returns:
the cloned data sample
- static currentTime()[source]
Returns the current system time suitable for data sample timestamps. Note: The python implementation uses time.time_ns, which unfortunately has limited accuracy under windows (16 ms).
- Returns:
an integer instance
- getContent()[source]
Get the contents of this sample as a QByteArray. Note that this is an efficient operation due to the copy on write semantics of QByteArray. It also asserts that the original contents cannot be modified.
In C++, make sure to keep an instance of the QByteArray until done with processing. Moreover, consider to use QByteArray::constData() for a pointer-to-memory access rather than QByteArray::data(), since the latter will eventually make an unnecessary deep copy of the encapsulated data.
- Returns:
QByteArray instance copy
- class nexxT.interface.Filter(dynInPortsSupported, dynOutPortsSupported, environment)[source]
Bases:
QObjectNote
Import this class with
from nexxT.interface import Filter.This class is the base class for defining a nexxT filter. A minimal nexxT filter class looks like this:
class SimpleStaticFilter(Filter): def __init__(self, environment): super().__init__(False, False, environment) pc = self.propertyCollection() self.sample_property = pc.getProperty("sample_property", 0.1, "a property for demonstration purpose") self.inPort = self.addStaticInputPort("inPort") self.outPort = self.addStaticOutputPort("outPort") def onPortDataChanged(self, inputPort): dataSample = inputPort.getData() newSample = DataSample.copy(dataSample) self.outPort.transmit(dataSample)
The constructor of classes derived from nexxT.interface.Filter must have a single argument environment which is passed through to this base class. It configures dynamic port usage with the two boolean flags. In the constructor, the filter can define and query properties and create static ports.
The onPortDataChanged is called whenever new data arrives on an input port. In the example above, a copy of the original data sample is returned.
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
nexxT::Filter- __init__(dynInPortsSupported, dynOutPortsSupported, environment)[source]
Filter Constructor.
- Parameters:
dynInPortsSupported – Flag whether this filter supports dynamic input ports
dynOutPortsSupported – Flag whether this filter supports dynamic output ports
environment – FilterEnvironment instance which shall be passed through from the filter constructor.
- addStaticInputPort(name, queueSizeSamples=1, queueSizeSeconds=None)[source]
Shortcut for generating a static input port and adding it to the filter. See also
nexxT.interface.Ports.InputPort()- Parameters:
name – The name of the input port
queueSizeSamples – The size of the input queue in samples
queueSizeSeconds – The size of the input queue in seconds
- Returns:
the new port instance
- addStaticOutputPort(name)[source]
Shortcut for generating a static output port and adding it to the filter. See also
nexxT.interface.Ports.OutputPort()- Parameters:
name – The name of the output port
- Returns:
the new port instance
- addStaticPort(port)[source]
Register a static port for this filter. Only possible in CONSTRUCTING state.
- Parameters:
port – InputPort or OutputPort instance
- Returns:
None
- environment()[source]
Returns the environment associated with this filter.
- Returns:
a FilterEnvironment instance
- getDynamicInputPorts()[source]
Get dynamic input ports of this filter. Only possible in and after INITIALIZING state.
- Returns:
list of dynamic input ports
- getDynamicOutputPorts()[source]
Get dynamic output ports of this filter. Only possible in and after INITIALIZING state.
- Returns:
list of dynamic output ports
- guiState()[source]
Return the gui state associated with this filter. Note: the gui state shall not be used for properties which are important for data transport, for these cases the propertyCollection() shall be used. Typical gui state variables are: the geometry of a user-managed window, the last directory path used in a file dialog, etc. The gui state might not be initialized during mockup-phase.
- Returns:
PropertyCollection instance
- onClose()[source]
This function can be overwritten for general de-initialization tasks (e.g. release resources needed to run the filter, close files, etc.). It is the opoosite to onOpen(…).
- Returns:
None
- onDeinit()[source]
This function can be overwritten for performing de-initialization tasks related to dynamic ports. It is the opposite to onInit(…)
- Returns:
None
- onInit()[source]
This function can be overwritten for performing initialization tasks related to dynamic ports.
- Returns:
None
- onOpen()[source]
This function can be overwritten for general initialization tasks (e.g. acquire resources needed to run the filter, open files, connecting to services etc.).
- Returns:
- onPortDataChanged(inputPort)[source]
This function can be overwritten to be notified when new data samples arrive at input ports. For each data sample arrived this function will be called exactly once.
- Parameters:
inputPort – the port where the data arrived
- Returns:
None
- onStart()[source]
This function can be overwritten to reset internal filter state. It is called before loading a new sequence.
- Returns:
None
- onSuggestDynamicPorts()[source]
Shall return the suggested dynamic ports of this filter. Prominent example is to return the streams contained in a HDF5 file. Note that it is safe to assume that the instance lives in the GUI thread, when this function is called from the nexxT framework.
- Returns:
listOfInputPortNames, listOfOutputPortNames
- propertyCollection()[source]
Return the property collection associated with this filter.
- Returns:
PropertyCollection instance
- removeStaticPort(port)[source]
Remove a static port of this filter. Only possible in CONSTRUCTING state.
- Parameters:
port – InputPort or OutputPort instance
- Returns:
None
- staticMetaObject = PySide6.QtCore.QMetaObject("Filter" inherits "QObject": )
- class nexxT.interface.FilterState[source]
Bases:
objectNote
Import this class with
from nexxT.interface import FilterState.This class defines an enum for the filter states. For reference, the filter’s lifecycle state diagram is shown here:
- class nexxT.interface.FilterSurrogate(dllUrls, name)[source]
Bases:
objectNote
Import this class with
from nexxT.interface import FilterSurrogate.This class acts as a surrogate to reference a filter from a DLL/shared object plugin from within python. It’s main purpose is the ability to announce these filters using python entry points. For this, create an instance of this class in one of your modules and refer to it by a ‘nexxT.filters’ entry point. Example:
from distutils.core import setup setup( # ... 'nexxT.filters' : [ 'examples.framework.CameraGrabber = nexxT.examples:CameraGrabber', ])
The surrogate creation of CameraGrabber is performed in
nexxT.examples:# SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2020 ifm electronic gmbh # # THE PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. # """ define FilterSurrogates for binary filters. """ from pathlib import Path import os from nexxT.interface import FilterSurrogate if os.environ.get("READTHEDOCS", None) is None: from nexxT.Qt import QtMultimedia # needed to load corresponding DLL before loading the nexxT plugin AviReader = FilterSurrogate( "binary://" + str((Path(__file__).parent.parent / "tests" / "binary" / "${NEXXT_PLATFORM}" / "${NEXXT_VARIANT}" / "test_plugins").absolute()), "VideoPlaybackDevice" ) """ Filter surrogate for the VideoPlaybackDevice class which is defined in a packaged shared object "test_plugins". """ CameraGrabber = FilterSurrogate( "binary://" + str((Path(__file__).parent.parent / "tests" / "binary" / "${NEXXT_PLATFORM}" / "${NEXXT_VARIANT}" / "test_plugins").absolute()), "CameraGrabber" ) """ Filter surrogate for the CameraGrabber class which is defined in a packaged shared object "test_plugins". """
- __init__(dllUrls, name)[source]
Create a FilterSurrogate instance.
- Parameters:
dllUrls – might be (1) a dictionary mapping variant names to URLs, variant names are usually “nonopt” and “release” or (2) a url string which will be mapped to the release variant Note that URLs for binary libraries (DLL’s or shared objects) are of the form “binary://<absolute-path-to-dll>”. The absolute path might contain variables like ${NEXXT_PLATFORM} or ${NEXXT_VARIANT}.
name – the name of the filter class or factory function
- nexxT.interface.InputPort
alias of
InputPortImpl
- class nexxT.interface.InputPortInterface(dynamic, name, environment)[source]
Bases:
PortThis abstract class defines the interface of an input port of a filter. In addition to the normal port attributes, there are two new attributes related to automatic buffering of input data samples. queueSizeSamples sets the maximum number of samples buffered (it can be None, if queueSizeSeconds is not None) queueSizeSeconds sets the maximum time of samples buffered (it can be None, if queueSizeSamples is not None) If both attributes are set, they are and-combined.
- ..note::
Usually nexxT is using a wrapped C++ class instead of this pure python version. In python there are no differences between the wrapped C++ class and this python class. The C++ interface is defined in
nexxT::InputPortInterface
- clone(newEnvironment)[source]
Return a copy of this port attached to a new environment.
- Parameters:
newEnvironment – the new FilterEnvironment instance
- Returns:
a new Port instance
- getData(delaySamples=0, delaySeconds=None)[source]
Return a data sample stored in the queue (called by the filter).
- Parameters:
delaySamples – 0 related the most actual sample, numbers > 0 relates to historic samples (None can be given if delaySeconds is not None)
delaySeconds – if not None, a delay of 0.0 is related to the current sample, positive numbers are related to historic samples (TODO specify the exact semantics of delaySeconds)
- Returns:
DataSample instance
- receiveAsync(dataSample, semaphore)[source]
Called from framework only and implements the asynchronous receive mechanism using a semaphore.
- Parameters:
dataSample – the transmitted DataSample instance
semaphore – a QSemaphore instance
- Returns:
None
- receiveSync(dataSample)[source]
Called from framework only and implements the synchronous receive mechanism. TODO implement
- Parameters:
dataSample – the transmitted DataSample instance
- Returns:
None
- setInterthreadDynamicQueue(enabled)[source]
If enabled is True, inter thread connections to this input port are dynamically queued for non-blocking behaviour.
This setting does not affect connections from within the same thread. This method can be called only during constructor or the onInit() method of a filter. The main use case is a recording filter where the QT signal/slot is allowed to buffer as many samples as allowed in the input port’s queue to prevent unwanted blocking behaviour.
Enabling this might cause a larger delay and might also consume a lot of memory.
- Parameters:
enabled – whether the dynamic queuing feature is enabled or not.
- Returns:
- setQueueSize(queueSizeSamples, queueSizeSeconds)[source]
Set the queue size of this port.
- Parameters:
queueSizeSamples – 0 related the most actual sample, numbers > 0 relates to historic samples (None can be given if delaySeconds is not None)
queueSizeSeconds – if not None, a delay of 0.0 is related to the current sample, positive numbers are related to historic samples
- Returns:
- staticMetaObject = PySide6.QtCore.QMetaObject("InputPortInterface" inherits "Port": )
- nexxT.interface.OutputPort
alias of
OutputPortImpl
- class nexxT.interface.OutputPortInterface(dynamic, name, environment)[source]
Bases:
PortThis abstract base class defines the interface of an output port of a filter.
- ..note::
Usually nexxT is using a wrapped C++ class instead of this pure python version. In python there are no differences between the wrapped C++ class and this python class. The C++ interface is defined in
nexxT::OutputPortInterface
- clone(newEnvironment)[source]
Return a copy of this port attached to a new environment.
- Parameters:
newEnvironment – the new FilterEnvironment instance
- Returns:
a new Port instance
- setupDirectConnection(inputPort)
Setup a direct (intra-thread) connection between outputPort and inputPort Note: both instances must live in same thread!
- Parameters:
outputPort – the output port instance to be connected
inputPort – the input port instance to be connected
- Returns:
None
- setupInterThreadConnection(inputPort, outputPortThread, width)
Setup an inter thread connection between outputPort and inputPort
- Parameters:
outputPort – the output port instance to be connected
inputPort – the input port instance to be connected
outputPortThread – the QThread instance of the outputPort instance
width – the width of the connection in DataSamples (0: infinite)
- Returns:
an InterThreadConnection instance which manages the connection (has to survive until connections is deleted)
- staticMetaObject = PySide6.QtCore.QMetaObject("OutputPortInterface" inherits "Port": Methods: #4 type=Signal, signature=transmitSample(PyObject), parameters=PyObject )
- transmit(dataSample)[source]
transmit a data sample over this port
- Parameters:
dataSample – sample to transmit
- transmitSample
- class nexxT.interface.Port(dynamic, name, environment)[source]
Bases:
QObjectThis class is the base class for ports. It is used mainly as structure, containing the 3 properties dynamic (boolean), name (str) and environment (a FilterEnvironment instance).
- ..note::
Usually nexxT is using a wrapped C++ class instead of this pure python version. In python there are no differences between the wrapped C++ class and this python class. The C++ interface is defined in
nexxT::Port
- INPUT_PORT = 0
- OUTPUT_PORT = 1
- __init__(dynamic, name, environment)[source]
Constructor.
- Parameters:
dynamic – boolean whether this is a dynamic port or not
name – the port name, given as a string
environment – the corresponding FilterEnvironment instance
- clone(newEnvironment)[source]
This function must be overwritten in inherited classes to create a clone of this port attached to a different environment.
- Parameters:
newEnvironment – the new FilterEnvironment instance
- Returns:
a new Port instance
- environment()[source]
Returns the environment instance managing this port
- Returns:
FilterEnvironment instance
- setName(name)[source]
Sets the port name
- Parameters:
name – the port name given as a string
- Returns:
None
- staticMetaObject = PySide6.QtCore.QMetaObject("Port" inherits "QObject": )
- class nexxT.interface.PropertyCollection[source]
Bases:
QObjectNote
Import this class with
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
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 thepropertyChangedsignal. 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
nexxT::PropertyCollection- defineProperty(name, defaultVal, helpstr, options=None, propertyHandler=None)[source]
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.
- Parameters:
name – the name of the property
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
helpstr – a help string for the user (presented as a tool tip)
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.
propertyHandler – a PropertyHandler instance, or None for automatic choice according to defaultVal
- Returns:
the current value of this property
- evalpath(path)[source]
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.
- Parameters:
path – a string
- Returns:
absolute path as string
- getProperty(name)[source]
return the property identified by name
- Parameters:
name – a string
- Returns:
the current property value
- propertyChanged
QT signal which is emitted after a property value of the collection has been changed by the user.
- Parameters:
pc – the PropertyCollection instance (i.e., the same as self.sender())
propName – the name of the property which has been changed.
- setProperty(name, value)[source]
Set the value of a named property.
- Parameters:
name – property name
value – the value to be set
- Returns:
None
- staticMetaObject = PySide6.QtCore.QMetaObject("PropertyCollection" inherits "QObject": Methods: #4 type=Signal, signature=propertyChanged(PyObject,QString), parameters=PyObject, QString #5 type=Slot, signature=setProperty(QString,PyObject), parameters=QString, PyObject )
- class nexxT.interface.PropertyHandler[source]
Bases:
objectNote
Import this class with
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:
class IntHandler(PropertyHandler): """ The property handler for integer properties; Supported options: min and max. """ def __init__(self, options): """ Constructor :param options: the options given to the defineProperty(...) function. """ for k in options: if k in ["min", "max"]: if not isinstance(options[k], int): raise PropertyParsingError(f"Unexpected type of option {k}; expected int.") else: raise PropertyParsingError(f"Unexpected option {k}; expected 'min' or 'max'.") self._options = options def options(self): """ return this handler's options :return: a python dict with the actual options. """ return self._options def fromConfig(self, value): """ import value from config file and return the adapted version. :param value: an integer is expected :return: the validated integer """ assert isinstance(value, (float, int, bool)) return self.validate(value) def toConfig(self, value): """ export value to config file and return the adapted version :param value: an integer is expected :return: the exported value """ assert isinstance(value, int) return value def toViewValue(self, value): """ create a view of this option value. :param value: the current option value :return: a string """ assert isinstance(value, int) return str(value) def validate(self, value): """ Validate an option value and return an adapted, valid value :param value: the value to be tested (an integer) :return: the adapted, valid value """ if isinstance(value, str): try: value = int(value) except ValueError: logger.warning("Cannot interpret value '%s' as int. Using 0.", value) value = 0 if "min" in self._options: if value < self._options["min"]: logger.warning("Adapted option value %d to minimum value %d.", value, self._options["min"]) return self._options["min"] if "max" in self._options: if value > self._options["max"]: logger.warning("Adapted option value %d to maximum value %d.", value, self._options["max"]) return self._options["max"] return int(value) def createEditor(self, parent): """ Creates a QSpinBox instance for GUI editing of integer values :param parent: the parent of the widget :return: a QSpinBox instance """ res = QSpinBox(parent) res.setFrame(False) if "min" in self._options: res.setMinimum(self._options["min"]) else: res.setMinimum(-2147483648) if "max" in self._options: res.setMaximum(self._options["max"]) else: res.setMaximum(2147483647) return res def setEditorData(self, editor, value): """ set the value of the QSpinBox :param editor: the instance returned by createEditor :param value: the option value (an integer) :return: None """ editor.setValue(value) def getEditorData(self, editor): """ return the currently edited value :param editor: the instance returned by createEditor :return: the integer value """ return self.validate(editor.value())
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
nexxT::PropertyHandler- createEditor(parent)[source]
This is called in QStyledItemDelegate::createEditor; creates an editor widget instance.
- Parameters:
parent – a QWidget instance
- Returns:
a QWidget instance
- fromConfig(value)[source]
Converts the value read from the json file into the native python format
- Parameters:
value – a QVariant instance
- Returns:
the native value (also a QVariant)
- getEditorData(editor)[source]
This is called in QStyledItemDelegate::setModelData; converts the value from the editor back to native python value.
- Parameters:
editor – the editor widget
- Returns:
a QVariant, the new native property value
- options()[source]
Returns the options set for this handler as a QVariantMap
- Returns:
a QVariantMap instance
- setEditorData(editor, value)[source]
This is called in QStyledItemDelegate::setEditorData; populates the editor widget with the actual data.
- Parameters:
editor – the editor widget as rezurned by createEditor
value – the current property value, given as native python value
- Returns:
None
- toConfig(value)[source]
Converts the native python format into a value suitable for json files.
- Parameters:
value – a QVariant instance (the native value)
- Returns:
the json value (also a QVariant)
Submodules
- nexxT.interface.DataSamples module
- nexxT.interface.Filters module
FilterFilter.__init__()Filter.addStaticInputPort()Filter.addStaticOutputPort()Filter.addStaticPort()Filter.environment()Filter.getDynamicInputPorts()Filter.getDynamicOutputPorts()Filter.guiState()Filter.onClose()Filter.onDeinit()Filter.onInit()Filter.onOpen()Filter.onPortDataChanged()Filter.onStart()Filter.onStop()Filter.onSuggestDynamicPorts()Filter.propertyCollection()Filter.removeStaticPort()Filter.staticMetaObject
FilterStateFilterSurrogate
- nexxT.interface.Ports module
InputPort()InputPortInterfaceInputPortInterface.clone()InputPortInterface.getData()InputPortInterface.interthreadDynamicQueue()InputPortInterface.queueSizeSamples()InputPortInterface.queueSizeSeconds()InputPortInterface.receiveAsync()InputPortInterface.receiveSync()InputPortInterface.setInterthreadDynamicQueue()InputPortInterface.setQueueSize()InputPortInterface.staticMetaObject
OutputPort()OutputPortInterfacePort
- nexxT.interface.PropertyCollections module
- nexxT.interface.Services module