Custom tools for viewers and custom toolbars¶
Writing a custom tool for a viewer toolbar¶
Here we take a look at how to create a tool to include in a viewer’s toolbar (either one of the built-in viewers or a custom viewer) There are two types of tools: ones that can be checked and unchecked, and ones that simply trigger an event when pressed, but do not remain pressed. These are described in the following two sub-sections.
The basic structure for a non-checkable tool is:
from glue.config import viewer_tool from glue.viewers.common.qt.tool import Tool @viewer_tool class MyCustomTool(Tool): icon = 'myicon.png' tool_id = 'custom_tool' action_text = 'Does cool stuff' tool_tip = 'Does cool stuff' shortcut = 'D' def __init__(self, viewer): super(MyCustomMode, self).__init__(viewer) def activate(self): pass def close(self): pass
The class-level variables set at the start of the class are as follows:
icon: this should be set either to the name of a built-in glue icon, or to the path to a PNG file to be used for the icon. Note that this should not be a
tool_id: a unique string that identifies this tool. If you create a tool that has the same
tool_idas an existing tool already implemented in glue, you will get an error.
action_text: a string describing the tool. This is not currently used, but would be the text that would appear if the tool was accessible by a menu.
tool_tip: this should be a string that will be shown when the user hovers above the button in the toolbar. This can include instructions on how to use the tool.
shortcut: this should be a string giving a key that the user can press when the viewer is active, which will activate the tool. This can include modifier keys, e.g.
'Ctrl+Shift+U', but can also just be a single key, e.g.
'K'. If present, the shortcut is added at the end of the tooltip. If multiple tools in a viewer have the same shortcut, a warning will be emitted, and only the first tool registered with a particular shortcut will be accessible with that shortcut.
When the user presses the tool icon, the
activate method is called. In this
method, you can write any code including code that may for example open a Qt
window, or change the state of the viewer (for example changing the zoom or
field of view). You can access the viewer instance with
Finally, when the viewer is closed the
close method is called, so you should
use this to do any necessary cleanup.
@viewer_tool decorator tells glue that this class represents a viewer
tool, and you will then be able to add the tool to any viewers (see
Customizing the content of a toolbar) using the
The basic structure for a checkable tool is similar to the above, but with an
deactivate method, and a
from glue.config import viewer_tool from glue.viewers.common.qt.tool import CheckableTool @viewer_tool class MyCustomButton(CheckableTool): icon = 'myicon.png' tool_id = 'custom_tool' action_text = 'Does cool stuff' tool_tip = 'Does cool stuff' status_tip = 'Instructions on what to do now' shortcut = 'D' def __init__(self, viewer): super(MyCustomMode, self).__init__(viewer) def activate(self): pass def deactivate(self): pass def close(self): pass
When the tool icon is pressed, the
activate method is called, and when the
button is unchecked (either by clicking on it again, or if the user clicks on
another tool icon), the
deactivate method is called. As before, when the
viewer is closed, the
close method is called. The
status_tip is a
message shown in the status bar of the viewer when the tool is active. This can
be used to provide instructions to the user as to what they should do next.
Customizing the content of a toolbar¶
When defining a tool as above, the
@viewer_tool decorator ensures that
the tool is registered with glue, but does not add it to any specific viewer.
Which buttons are shown for a viewer is controlled by the
attribute on viewers:
>>> from glue.viewers.image.qt import ImageWidget >>> ImageWidget.tools ['select:rectangle', 'select:xrange', 'select:yrange', 'select:circle', 'select:polygon', 'image:colormap']
The strings in the
tools list correspond to the
tool_id attribute on the
tool classes. If you want to add an existing or custom button to a viewer, you
can therefore simply do e.g.:
from glue.viewers.image.qt import ImageWidget ImageWidget.tools.append('custom_tool')
Including toolbars in custom viewers¶
When defining a data viewer (as described in Writing a fully customized Qt viewer (advanced)), it
is straightforward to add a toolbar that can then be used to add tools. To do
this, when defining your
you should also specify the
attributes, which should give the class to use for the toolbar, and the default
tools that should be present in the toolbar:
from glue.viewers.common.qt.data_viewer import DataViewer from glue.viewers.common.qt.toolbar import BasicToolbar class MyViewer(DataViewer): _toolbar_cls = BasicToolbar tools = ['custom_tool']
In the example above, the viewer will include an toolbar with one tool (the one we defined above). There are currently two main classes available for toolbars:
BasicToolbar: this is the most basic kind of toolbar - it comes with no tools by default.
MatplotlibViewerToolbar: this is a subclass of
BasicToolbarthat includes the standard Matplotlib buttons by default (home, zoom, pan, etc.). This toolbar can only be used if your data viewer includes a Matplotlib canvas accessible at
Note that the toolbar is set up after
__init__ has run. Therefore, if you
want to do any custom set-up to the toolbar after it has been set up, you
should overload the
initialize_toolbar method, e.g:
class MyViewer(DataViewer): _toolbar_cls = BasicToolbar tools = ['custom_tool'] def initialize_toolbar(self): super(MyViewer, self).initialize_toolbar() # custom code here
initialize_toolbar (and elsewhere in the class) you can then access the
tool instances using
self.toolbar.tools (which is a dictionary where each
key is a
The following tools are available by default (note that not all tools can be used in all viewers, click on each tool class name to find out more):