fsleyes.actions¶
This package provides a collection of actions, classes - the
Action class and the ActionProvider
class, and the action() and toggleAction() decorators.
The Action class represents some sort of action which may be
performed, enabled and disabled, and may be bound to a GUI menu item or
button. The ActionProvider class represents some entity which can
perform one or more actions. As the FSLeyesPanel class derives from
ActionProvider pretty much everything in FSLeyes is an
ActionProvider.
Many of the modules in this package also contain standalone functions for doing
various things, such as the screenshot.screenshot() function, and the
loadoverlay.loadImage() function.
The action() and toggleAction() functions are intended to be used
as decorators upon the methods of a class which derives from
ActionProvider. For example:
>>> import fsleyes.actions as actions
>>> class Thing(actions.ActionProvider):
@actions.action
def doFirstThing(self):
print 'First thing done'
@actions.action
def doSecondThing(self):
print 'Second thing done'
@actions.toggleAction
def toggleOtherThing(self):
print 'Other thing toggled'
In this example, when an instance of Thing is defined, each of the methods
that are defined as actions will be available through the methods defined in
the ActionProvder. For example:
>>> t = Thing()
>>> print t.getActions()
[('doFirstThing', Action(doFirstThing)),
('doSecondThing', Action(doSecondThing)),
('toggleOtherThing', ToggleAction(toggleOtherThing))]
You can enable/disable actions through the ActionProvider.enableAction()
and ActionProvider.disableAction() methods:
>>> t.disableAction('doFirstThing')
>>> t.doFirstThing()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/.../fsleyes/actions/__init__.py", line 139, in __call__
self.__name))
fsleyes.actions.ActionDisabledError: Action doFirstThing is disabled
It is useful to know that each method on the t instance has actually been
replaced with an Action instance, which encapsulates the method.
Using this knowledge, you can access the Action instances directly:
>>> t.doFirstThing.enabled = True
>>> t.doFirstThing()
First thing done
The Action.bindToWidget() method allows a widget to be bound to an
Action. For example:
# We're assuming here that a wx.App, and
# a parent window, has been created
>>> button = wx.Button(parent, label='Do the first thing!')
>>> t.doSecondThing.bindToWidget(parent, button, wx.EVT_BUTTON)
All bound widgets of an Action can be accessed through the
Action.getBoundWidgets() method, and can be unbound via the
Action.unbindAllWidgets() method.
This module also provides two classes which allow a widget to be automatically
created for, and bound to an Action or ToggleAction (through the
props.build package):
Extends the
props.Buttonclass to encapsulate anActioninstance.Extends the
props.Toggleclass to encapsulate aToggleActioninstance.
-
fsleyes.actions.action(*args, **kwargs)[source]¶ A decorator which identifies a class method as an action.
-
fsleyes.actions.toggleAction(*args, **kwargs)[source]¶ A decorator which identifies a class method as a toggle action.
-
fsleyes.actions.toggleControlAction(*args, **kwargs)[source]¶ A decorator which identifies a class method as a
ToggleControlPanelAction.
-
class
fsleyes.actions.ActionProvider(overlayList, displayCtx)[source]¶ Bases:
objectThe
ActionProviderclass is intended to be used as a base class for classes which contain actions. Theaction()andtoggleAction()functions can be used as decorators on class methods, to denote them as actions.-
__init__(overlayList, displayCtx)[source]¶ Create an
ActionProvider.- Parameters
overlayList – The
OverlayList.displayCtx – The
DisplayContext.
-
property
overlayList¶ Return a reference to the
OverlayList.
-
property
displayCtx¶ Return a reference to the
DisplayContext.
-
destroy()[source]¶ Must be called when this
ActionProvideris no longer needed. Calls theAction.destroy()method of allActioninstances.
-
hasAction(name)[source]¶ Return
Trueif thisActionProviderhas an action with the given name,Falseotherwise
-
getActions()[source]¶ Return a list containing the
(name, Action)of allActioninstances in thisActionProvider.Sub-classes may wish to override this method to enforce a specific ordering of their actions.
Note
The list returned by this method may contain:
Entries equal to
(None, None). This is used as a hint for GUIs which display action widgets/menu items to indicate that a separator should be inserted.Entries equal to
(name, [(name, Action), ...]). This is used as a hint for GUIs that the nested list of actions should appear as a sub-menu with the specifiedname.
-
__dict__= mappingproxy({'__module__': 'fsleyes.actions', '__doc__': 'The ``ActionProvider`` class is intended to be used as a base class for\n classes which contain actions. The :func:`action` and :func:`toggleAction`\n functions can be used as decorators on class methods, to denote them as\n actions.\n ', '__init__': <function ActionProvider.__init__>, 'overlayList': <property object>, 'displayCtx': <property object>, 'destroy': <function ActionProvider.destroy>, 'getAction': <function ActionProvider.getAction>, 'hasAction': <function ActionProvider.hasAction>, 'enableAction': <function ActionProvider.enableAction>, 'disableAction': <function ActionProvider.disableAction>, 'getActions': <function ActionProvider.getActions>, '__dict__': <attribute '__dict__' of 'ActionProvider' objects>, '__weakref__': <attribute '__weakref__' of 'ActionProvider' objects>})¶
-
__module__= 'fsleyes.actions'¶
-
__weakref__¶ list of weak references to the object (if defined)
-
-
class
fsleyes.actions.ActionFactory(actionType, *args, **kwargs)[source]¶ Bases:
objectThe
ActionFactoryis used by theaction()andtoggleAction()decorators. Its job is to createActioninstances forActionProviderinstances.Warning
This class contains difficult-to-understand code. Read up on decorators and descriptors before proceeding.
Note
This class has no use outside of this module, except for use with custom
Action/ToggleActionsub-classes and corresponding decorators (along the lines ofaction()andtoggleAction()). A custom decorator simply needs to returnActionFactory(CustomActionClass, *args, **kwargs), where the*argsand**kwargsare the arguments passed to theActionsub-class.See the
toggleControlAction()decorator for an example.Boring technical details
Consider the following class:
class MyThing(ActionProvider): @action def myAction(self): # do things here
The
MyClass.myActionmethod has been marked as an action, using theaction()decorator. However, theaction()decorator cannot create anActioninstance at the point of class definition, because this would lead to a singleActioninstance being shared by multipleMyThinginstances. We need to be able to create anActioninstance for everyMyThinginstance, whilst still allowing the action decorator to be used on class methods.So when the
action()ortoggleAction()is used in a class definition, anActionFactoryis created, and used as the decorator of the unbound class method.Later on, when the
ActionFactorydetects that it being is accessed through an instance of the class (aMyThinginstance in the example above), it creates anActioninstance, and then replaces itself with thisActioninstance - theActioninstance becomes the decorator of the bound method. This is possible because theActionFactoryis a descriptor - it uses the__get__()method so it can differentiate between class-level and instance-level accesses of the decorated method.The
ActionFactorysupports class-method decorators both with and without arguments. While neither theAction, nor theToggleActionclasses accept any optional arguments, this may be useful for custom sub-classes, i.e.:class MyThing(ActionProvider): @action def myAction(self): # do things here @customAction() def myAction2(self): # do things here @otherCustomAction(arg1=8) def myAction3(self): # do things here
Todo
Merge/replace this class with the
memoize.Instanceifydecorator.-
__init__(actionType, *args, **kwargs)[source]¶ Create an
ActionFactory.- Parameters
actionType – The action type (e.g.
ActionorToggleAction).
The remaining arguments may comprise a single callable object, (an
@actionstyle decorator was used) or a collection of arguments passed to the decorator (an@action(...)style decorator was used).
-
__call__(func=None)[source]¶ If this
ActionFactorywas instantiated through a brackets-style decorator (e.g.@action(arg1=1, arg2=2)), this method is called immediately after__init__(), with a reference to the decorated function. Otherwise, (an@actionstyle decorator was used), this method should never be called.
-
__get__(instance, cls)[source]¶ When this
ActionFactoryis accessed through an instance, anActioninstance is created. ThisActionFactoryis then replaced by theActioninstance.If this
ActionFactoryis accessed through a class, the encapsulated function is returned.
-
__dict__= mappingproxy({'__module__': 'fsleyes.actions', '__doc__': 'The ``ActionFactory`` is used by the :func:`action` and\n :func:`toggleAction` decorators. Its job is to create :class:`Action`\n instances for :class:`ActionProvider` instances.\n\n\n .. warning:: This class contains difficult-to-understand code. Read up\n on decorators and descriptors before proceeding.\n\n\n .. note:: This class has no use outside of this module, except for use\n with custom :class:`.Action`/:class:`.ToggleAction` sub-classes\n and corresponding decorators (along the lines of :func:`.action`\n and :func:`.toggleAction`). A custom decorator simply needs\n to return ``ActionFactory(CustomActionClass, *args, **kwargs)``,\n where the ``*args`` and ``**kwargs`` are the arguments passed to\n the :class:`Action` sub-class.\n\n See the :func:`toggleControlAction` decorator for an example.\n\n\n *Boring technical details*\n\n\n Consider the following class::\n\n class MyThing(ActionProvider):\n\n @action\n def myAction(self):\n # do things here\n\n\n The ``MyClass.myAction`` method has been marked as an action, using the\n :func:`action` decorator. However, the :func:`action` decorator cannot\n create an :class:`Action` instance at the point of class definition,\n because this would lead to a single ``Action`` instance being shared by\n multiple ``MyThing`` instances. We need to be able to create an ``Action``\n instance for every ``MyThing`` instance, whilst still allowing the action\n decorator to be used on class methods.\n\n\n So when the :func:`action` or :func:`toggleAction` is used in a class\n definition, an ``ActionFactory`` is created, and used as the decorator\n of the unbound class method.\n\n\n Later on, when the ``ActionFactory`` detects that it being is accessed\n through an instance of the class (a ``MyThing`` instance in the example\n above), it creates an :class:`Action` instance, and then replaces itself\n with this ``Action`` instance - the ``Action`` instance becomes the\n decorator of the bound method. This is possible because the\n ``ActionFactory`` is a descriptor - it uses the :meth:`__get__` method\n so it can differentiate between class-level and instance-level accesses\n of the decorated method.\n\n\n The ``ActionFactory`` supports class-method decorators both with and\n without arguments. While neither the :class:`.Action`, nor the\n :class:`.ToggleAction` classes accept any optional arguments, this may be\n useful for custom sub-classes, i.e.::\n\n class MyThing(ActionProvider):\n\n @action\n def myAction(self):\n # do things here\n\n @customAction()\n def myAction2(self):\n # do things here\n\n @otherCustomAction(arg1=8)\n def myAction3(self):\n # do things here\n\n\n .. todo:: Merge/replace this class with the :class:`.memoize.Instanceify`\n decorator.\n ', '__init__': <function ActionFactory.__init__>, '__call__': <function ActionFactory.__call__>, '__get__': <function ActionFactory.__get__>, '__dict__': <attribute '__dict__' of 'ActionFactory' objects>, '__weakref__': <attribute '__weakref__' of 'ActionFactory' objects>})¶
-
__module__= 'fsleyes.actions'¶
-
__weakref__¶ list of weak references to the object (if defined)
-
-
class
fsleyes.actions.ActionButton(actionName, classType=None, actionArgs=None, actionKwargs=None, **kwargs)[source]¶ Bases:
__main__.MockClassExtends the
props.Buttonclass to encapsulate anActioninstance.Only actions which are defined using the
action()ortoggleAction()decorator are supported.-
__init__(actionName, classType=None, actionArgs=None, actionKwargs=None, **kwargs)[source]¶ Create an
ActionButton.- Parameters
actionName – Name of the action
classType – The type which defines the action.
kwargs – Passed to the
props.Buttonconstructor.
-
_ActionButton__onButton(instance, widget)¶ Called when the button is pushed. Runs the action.
-
_ActionButton__setup(instance, parent, widget)¶ Called when the button is created. Binds the button widget to the
Actioninstance.
-
__module__= 'fsleyes.actions'¶
-
-
class
fsleyes.actions.ToggleActionButton(actionName, icon, actionArgs=None, actionKwargs=None, **kwargs)[source]¶ Bases:
__main__.MockClassExtends the
props.Toggleclass to encapsulate aToggleActioninstance.Only actions which are defined using the
action()ortoggleAction()decorator are supported.-
__init__(actionName, icon, actionArgs=None, actionKwargs=None, **kwargs)[source]¶ Create a
ToggleActionButton.- Parameters
actionName – Name of the action
icon – One or two icon file names to use on the button.
actionArgs – Positional arguments to pass to the
ToggleActionwhen it is invoked.actionKwargs – Keyword arguments to pass to the
ToggleActionwhen it is invoked.kwargs – Passed to the
props.Toggleconstructor.
-
_ToggleActionButton__onToggle(instance, widget)¶ Called when the widget is toggled. Runs the action.
-
_ToggleActionButton__setup(instance, parent, widget)¶ Called when the toggle widget is created. Binds the widget to the
ToggleActioninstance.
-
__module__= 'fsleyes.actions'¶
-