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.
Non-checkable tools#
The basic structure for a non-checkable tool is:
from glue.config import viewer_tool
from glue.viewers.common.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 aQIcon
object.tool_id
: a unique string that identifies this tool. If you create a tool that has the sametool_id
as 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+A'
or'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 self.viewer
.
Finally, when the viewer is closed the close
method is called, so you should
use this to do any necessary cleanup.
The @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 tool_id
.
Checkable tools#
The basic structure for a checkable tool is similar to the above, but with an
additional deactivate
method, and a status_tip
attribute:
from glue.config import viewer_tool
from glue.viewers.common.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 tools
class-level
attribute on viewers:
>>> from glue.viewers.image.qt import ImageViewer
>>> ImageViewer.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 ImageViewer
ImageViewer.tools.append('custom_tool')
Including toolbars in custom viewers#
When defining a data viewer (as described in Writing a custom viewer for glue with Qt), it
is straightforward to add a toolbar that can then be used to add tools. To do
this, when defining your
DataViewer
subclass,
you should also specify the _toolbar_cls
and tools
class-level
attributes, which should give the class to use for the toolbar, and the default
tools that should be present in the toolbar:
from glue_qt.viewers.common.data_viewer import DataViewer
from glue_qt.viewers.common.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). Currently the only toolbar class that is defined
is BasicToolbar
.
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
In 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 tool_id
).
By default, tools are inherited from parent classes, but this can be controlled
using the inherit_tools
class-level attribute - for example, the following
will result in only the custom_tool
being available, and nothing else:
class MyImageViewer(ImageViewer):
tools = ['custom_tool']
inherit_tools = False
Available tools#
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):
Tool ID |
Class |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|