Properties are variables (in the sense defined in the pdk.Variables module)
that are used as instance attributes. They are particularly useful for
validating user input in interactive sessions.
takes care of scanning through the property declarations in a class (and its
base classes) and initializes all properties with their default value
(constructor)
performs the property value changes (configure method)
prints out help on selected or on all properties (help method)
provides methods for property queries (getProperties and getProperty
methods) and dynamic declaration of new properties (addProperty method)
A good use case are device drivers, as it is demonstrated in the example code
in this module. Another useful application are the classes in the
pdk.Gui.Widgets.MonitoringWidgets module, which provide a set of widgets that
monitor the value of a property in a bi-directional fashion (i.e., the widget
value changes when the property changes and vice versa).
This code incorporates ideas taken from Graphite, which was originally written
written by Joseph and Michelle Strout in 1999.
adds handling of components to the basic PropertyManager class
Detail:
a component is an object that is accessible as an attribute of
the container object. Component properties are accessed with
this notation:
<component name>_<property name>
Note that you must not initialize component properties in the
constructor call; rather, set up the components after the
instance has been created by calling the addComponent method,
and then call configure to initialize the components.
adds signalling and XML registry updating to the
PropertyManager
Detail:
this is implemented by overwriting the PropertyManager.configure
to also emit a signal and/or register a property value change.
Note that, whith this implementation, neither setting the
initialization values for the properties (in the constructor)
nor setting them directly (as in foo.bar=foobar) does
trigger a signal or register a change.
Note also that, by default, a Signal instance is created with
a lambda returning the current value of the property as send
function. To override this, manually call the .initializeSignal
method with the signal object/send function combination
of your choice (see the initializeWidget method of
pdk.Gui.WidgetStateManagers._WidgetStateManager for an example).
objectIdString: unique (within the application) string
representation of the object the properties of which are being
managed
enableSignalling: specifies whether property changes should
trigger a corresponding signal to be sent in this object or
not
xmlRegistry: if passed, this has to be a
pdk.DataBaseClasses.XmlReadWriteDataBase instance (i.e., a
DOM tree) that can then be used to store the current
property values for this object, most conveniently with the
.storePropertiesToRegistry method (which will ignore
read-only properties, however!). In this case, the objectIdString
parameter specifies the target node in the DOM tree (as an
underscore-separated path starting from the root node) that
will be used to store the property data
classes derived from PropertyManager may define new
properties in a "PROPERTIES" dictionary. During instantiation,
all base classes are traversed and all their property
definitions are added to the definitions of the derived class.
Property names are all lowercase to distinguish them from
local instance variables as well as from special keywords
needed for implementing the property behavior (which are
all uppercase).
Properties are implemented as restricted attributes using
a specialized descriptor (see
pdk.PropertyManagers.ManagedPropertyDescriptor).
The constructor takes arbitrary initial value for the defined
properties and the main method, .configure allows for
simultaneous runtime configuration of multiple properties. As
described in more detail in the pdk.Properties module, each
property can define callbacks to be triggered upon various
actions (e.g., a get callback when a property is accessed).
calling the .configure method for a read-only attribute of
non-None value will raise an error
if the callbacks for a property rely on the constructor
having finished its work, set the AUTOINIT flag for this
property to False and then call configure or
setToDefaultValue explicitly
dynamically adding/modifying properties to/of a base class
will not be reflected in derived classes, as each class
collects the properties from all bases only once from the
static class namespace (you can call
._updatePropertiesFromBases on derived classes to update
the property dictionary)
property definitions in base classes can be overridden by
defining a property with the same name in a derived class.
Base classes are taversed in the Python-specific
left-to-right manner
set new defaults for properties of this class (and derived
classes) given in **propertyD. Note that the defaults are also
changed for the current instance.
set new defaults for the properties of this instance given in
propertyD. Note that, if a property is currently set to its old
default value, it will automatically be set to its new default value.
updates the properties of this instance with the new properties
provided in propertyD. Raises a KeyError if propertyD contains
an undefined property name; raises a ValueError, if any value in
propertyD is not a Property instance.