fsleyes_props
fsleyes_props
is a framework for event-driven programming using python
descriptors, similar in functionality to, and influenced by Enthought Traits.
Example usage
>>> import fsleyes_props as props
>>> class PropObj(props.Props):
myProperty = props.Boolean()
>>> myPropObj = PropObj()
# Access the property value as a normal attribute:
>>> myPropObj.myProperty = True
>>> myPropObj.myProperty
True
# access the props.Boolean instance:
>>> myPropObj.getProp('myProperty')
<props.prop.Boolean at 0x1045e2710>
# access the underlying props.PropertyValue object
>>> myPropObj.getPropVal('myProperty')
<props.prop.PropertyValue instance at 0x1047ef518>
# Receive notification of property value changes
>>> def myPropertyChanged(value, *args):
print('New property value: {}'.format(value))
>>> myPropObj.addListener(
'myProperty', 'myListener', myPropertyChanged)
>>> myPropObj.myProperty = False
New property value: False
# Remove a previously added listener
>>> myPropObj.removeListener('myListener')
Package structure
To use fsleyes_props
, your first step will be to define a subclass of
HasProperties
(a.k.a. Props
), which contains one or more
PropertyBase
class attributes (see the properties_types
module for the available types).
Once you have an instance of your HasProperties
class, you can then create
a GUI for it using the functions defined in the build
and
widgets
modules, and the GUI specification building blocks defined in
the build_parts
module. You can also generate a command-line interface
using the functions defined in the cli
module.
All of the classes and functions referred to above are available in the
fsleyes_props
namespace, so you only need to import fsleyes_props
to
access them. You will however need to call the initGUI()
function if you
want to use any of the GUI generation functionality, before they are made
available at the fsleyes_props
namespace level.
Boring overview
Lots of the code in this package is probably very confusing. First of all, you will need to understand python descriptors. Descriptors are a way of adding properties to python objects, and allowing them to be accessed as if they were just simple attributes of the object, but controlling the way that the attributes are accessed and assigned.
The following link provides a good overview, and contains the ideas which form the basis for the implementation in this package:
And if you’ve got 30 minutes, this video gives a very good introduction to descriptors:
A HasProperties
subclass contains a collection of
PropertyBase
instances as class attributes. When an instance of the
HasProperties
class is created, a PropertyValue
object is
created for each of the PropertyBase
instances (or a
PropertyValueList
for ListPropertyBase
instances). Each
of these PropertyValue
instances encapsulates a single value, of any type
(a PropertyValueList
instance encapsulates multiple PropertyValue
instances). Whenever this value changes, the PropertyValue
instance
notifies any registered listeners of the change.
Notification
Application code may be notified of property changes by registering a callback
listener on a PropertyValue
object, via the equivalent methods:
Such a listener will be notified of changes to the PropertyValue
object
managed by the PropertyBase
object, and associated with the
HasProperties
instance. For ListPropertyBase
properties, a listener
registered through one of the above methods will be notified of changes to the
entire list. Alternately, a listener may be registered with individual items
contained in the list (see PropertyValueList.getPropertyValueList()
).
Validation
When a PropertyValue
accepts a new value, it passes the value to the
PropertyBase.validate()
method of its parent PropertyBase
instance
to determine whether the new value is valid. The PropertyValue
object
may allow its underlying value to be set to something invalid, but it will
tell registered listeners whether the new value is valid or
invalid. PropertyValue
objects can alternately be configured to raise a
ValueError
on an attempt to set them to an invalid value, but this has
some caveats - see the PropertyValue
documentation. Finally, to make things
more confusing, some PropertyBase
types will configure their
PropertyValue
objects to perform implicit casts when the property value is
set.
The default validation logic of most PropertyBase
objects can be
configured via attributes. For example, the Number
property
allows minval
and maxval
attributes to be set. These may be set via
PropertyBase
constructors, (i.e. when it is defined as a class attribute
of a HasProperties
definition), and may be queried and changed on
individual HasProperties
instances via the
HasProperties.getAttribute()
/HasProperties.setAttribute()
methods; similarly named methods are also available on PropertyBase
instances. Some PropertyBase
classes provide additional convenience
methods for accessing their attributes (e.g. :meth`.Choice.addChoice`).
Binding and Synchronisation
Properties from different HasProperties
instances may be bound to each
other, so that changes in one are propagated to the other - see the
bindable
module. Building on this is the syncable
module and
its SyncableHasProperties
class, which allows a one-to-many (one
parent, multiple children) synchronisation hierarchy to be maintained, whereby
all the properties of a child instance are by default synchronised to those of
the parent, and this synchronisation can be independently enabled/disabled for
each property. To use this functionality, simply inherit from the
SyncableHasProperties
class instead of the HasProperties
class.
API overview
Property types
The following classes are provided as building-blocks for your application code:
Base class for classes which contain |
|
An extension to the |
|
A property which encapsulates any value. |
|
A property which encapsulates a |
|
A |
|
A |
|
A |
|
A property which encapsulates a string. |
|
A property which represents a file or directory path. |
|
A property which may only be set to one of a set of predefined values. |
|
A property which represents a list of items, of another property type. |
|
A property which represents a RGBA colour, stored as four floating point values in the range |
|
A property which encapsulates a |
|
A property which represents numeric bounds in any number of dimensions, as long as that number is no more than 4. |
|
A property which represents a point in some n-dimensional (up to 4) space. |
Command line and string serialisation
The following functions are provided to manage command-line argument generation and parsing:
Apply arguments to a |
|
Adds arguments to the given |
|
Given a |
The following functions are provided for serialisation/deserialisation of
property values to/from strings (equivalent methods are also available on
HasProperties
instances):
Get the value of the named property from the given |
|
Deserialise the given string, under the assumption that it is a serialised value of the named property from the given |
GUI specification/generation
The following classes are provided for you to create GUI specifications:
Superclass for |
|
Represents a button which, when clicked, will call a specified callback function. |
|
Represents a toggle widget of some sort (e.g. a check box, or a toggle button) which, when clicked, calls a specified callback function. |
|
Represents a static text label. |
|
Represents a widget which is used to modify a property value. |
|
Represents a collection of other |
|
A |
|
A group representing a GUI panel, whose children are laid out horizontally. |
|
A group representing a GUI panel, whose children are laid out vertically. |
If the initGUI()
function is called, the following GUI-related functions
will be made available in the fsleyes_props
package namespace:
Given |
|
Creeates a widget for a specific value in the specified list property. |
|
Creates a widget for every value in the given list property. |
|
Creates a button which controls synchronisation of the specified property on the given |
|
Binds the given widget to the specified property. |
|
Unbinds the given widget from the specified property, assumed to have been previously bound via the |
|
Binds the given sequence of widgets to each of the values in the specified list property. |
|
Builds a GUI interface which allows the properties of the given |
|
Convenience method which embeds the result of a call to |
Miscellaneous
The suppress()
module provides some context managers allowing
notification of properties to be suppressed in a with
statement.