Creating an extension
- What is an OpenSesame extension?
- Relevant files
- Extension information
- Writing the extension code
- Writing a setup.py and uploading to PyPi
- Examples
- Event overview
- change_experiment
- change_item
- close
- delete_item
- heartbeat
- ide_jump_to_line
- ide_new_file
- ide_save_current_file
- image_annotations_detect
- jupyter_exception_occurred
- jupyter_execute_finished
- jupyter_execute_result_text
- jupyter_execute_start
- jupyter_interrupt
- jupyter_restart
- jupyter_run_code
- jupyter_run_system_command
- jupyter_show_prompt
- jupyter_write
- new_item
- new_linked_copy
- notify
- open_experiment
- open_item
- pause_experiment
- prepare_change_experiment
- prepare_delete_item
- prepare_open_item
- prepare_purge_unused_items
- prepare_regenerate
- prepare_rename_item
- purge_unused_items
- pyqode_clear_breakpoints
- pyqode_resume_auto_backend_restart
- pyqode_select_indentation_mode
- pyqode_suspend_auto_backend_restart
- regenerate
- register_editor
- rename_item
- resume_experiment
- run_experiment_canceled
- save_experiment
- startup
- unregister_editor
What is an OpenSesame extension?
Extensions add arbitrary functionality to the OpenSesame user interface. For example, an extension can add a new entry to the main toolbar or the menubar. To add functionality that you can use in experiments, you need a plugin:
Relevant files
Let's assume that your extension is called my_extension
. In that case, your extension corresponds to a folder called my_extension
, which contains at least the following 2 files:
MyExtension/
info.yaml
MyExtension.py
Extension information
Extension information is defined in info.yaml
. This works the same way as for plugins, with the exception that you don't define any controls. For more information, see:
Writing the extension code
The main extension code is placed in MyExtension.py
. This file has one class, MyExtension
(the same name as the file), which inherits libqtopensesame.extensions.BaseExtension
. So a basic (non-functional) extension class looks like this:
from libqtopensesame.extensions import BaseExtension
class MyExtension(BaseExtension):
pass
Activating an extension through the menu/ toolbar
An extension can appear in the menu or main toolbar of OpenSesame. This requires that you define several fields in info.yaml
:
label: Example extension
icon: go-next
tooltip: Some tooltip
menu:
index: 0
separator_after: false
separator_before: false
submenu: Example
toolbar:
index: -1
separator_after: false
separator_before: true
The label
is the text that will appear in the menu. The icon
is a freedesktop-compliant icon name that specifies the icon that will appear in the menu and/ or toolbar. The index
gives the position of the extension in the menu/ toolbar, and works like a list
index. That is, negative values are relative to the last entry, where -1 puts your extension at the end.
To have your extension respond to menu/ toolbar activation, implement the activate()
method:
from libopensesame.oslogging import oslogger
from libqtopensesame.extensions import BaseExtension
class MyExtension(BaseExtension):
def activate(self):
oslogger.info('My extension was activated!')
Listening for events
OpenSesame fires events whenever something important happens. For example, the save_experiment
event is fired when an experiment is saved. To have your extension listen to an event, simply implement a method with the name event_[event name]
.
from libopensesame.oslogging import oslogger
from libqtopensesame.extensions import BaseExtension
class MyExtension(BaseExtension):
def event_save_experiment(self, path):
oslogger.info(f'Event fired: save_experiment(path={path})')
Note that some events take keyword arguments, such as path
in the case of save_experiment
. The keyword signature of your function must match the expected keyword signature. A list of events can be found in the example extension.
Writing a setup.py and uploading to PyPi
See:
Examples
For a working example, see:
-
Other examples can be found in the
opensesame_extensions
folder included with OpenSesame.
Event overview
This overview lists all events that are fired somewhere in the code, and that your extenstion can therefore listen to by implementing the corresponding event_[eventname]()
functions.
change_experiment
Fired in: general_properties.py
extension_manager.fire(u'change_experiment')
change_item
Fired in: sequence.py
extension_manager.fire(u'change_item', name=self.name)
Fired in: qtitem.py
extension_manager.fire(u'change_item', name=self.name)
Fired in: loop.py
extension_manager.fire(u'change_item', name=self.name)
close
Fired in: qtopensesame.py
extension_manager.fire(u'close')
delete_item
Fired in: qtitem_store.py
extension_manager.fire(u'delete_item', name=name)
heartbeat
Fired in: multiprocess_runner.py
extension_manager.fire(u'heartbeat')
ide_jump_to_line
Fired in: SymbolSelector.py
extension_manager.fire('ide_jump_to_line', lineno=lineno)
Fired in: OpenSesameIDE.py
extension_manager.fire('ide_jump_to_line', lineno=line_number)
ide_new_file
Fired in: JupyterNotebook.py
extension_manager.fire(u'ide_new_file', source=code, ext=ext)
ide_save_current_file
Fired in: OpenSesameIDE.py
extension_manager.fire('ide_save_current_file')
image_annotations_detect
Fired in: JupyterNotebook.py
extension_manager.fire(u'image_annotations_detect', code=code)
jupyter_exception_occurred
Fired in: transparent_jupyter_widget.py
extension_manager.fire('jupyter_exception_occurred')
jupyter_execute_finished
Fired in: transparent_jupyter_widget.py
extension_manager.fire('jupyter_execute_finished')
jupyter_execute_result_text
Fired in: transparent_jupyter_widget.py
extension_manager.fire('jupyter_execute_result_text', text=text)
jupyter_execute_start
Fired in: transparent_jupyter_widget.py
extension_manager.fire('jupyter_execute_start')
jupyter_interrupt
Fired in: OpenSesameIDE.py
extension_manager.fire(u'jupyter_interrupt')
jupyter_restart
Fired in: console_bridge.py
extension_manager.fire(u'jupyter_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire(u'jupyter_restart')
jupyter_run_code
Fired in: menubar.py
extension_manager.fire('jupyter_run_code',
code=command)
jupyter_run_system_command
Fired in: JupyterNotebook.py
extension_manager.fire('jupyter_run_system_command', cmd=cmd)
jupyter_show_prompt
Fired in: console_bridge.py
extension_manager.fire(u'jupyter_show_prompt')
jupyter_write
Fired in: console_bridge.py
extension_manager.fire(u'jupyter_write', msg=s)
new_item
Fired in: tree_overview.py
extension_manager.fire(u'new_item', name=item.name,
_type=item.item_type)
new_linked_copy
Fired in: tree_overview.py
extension_manager.fire('new_linked_copy', name=item_name)
notify
Fired in: sequence.py
extension_manager.fire(u'notify',
message=_(u'Sequence contains non-existing item: %s')
Fired in: qtitem.py
extension_manager.fire(u'notify',
message=_(u'"%s" is set to a variable or '
u'unknown value and can only be edited through '
u'the script.')
Fired in: qtitem.py
extension_manager.fire(u'notify',
message=_(u'"%s" is defined using '
'variables and can only be edited through the '
'script.')
Fired in: qtitem.py
extension_manager.fire(u'notify',
message=_(u'"%s" is defined using '
u'variables or has an invalid value, and can only be '
u'edited through the script.')
Fired in: logger.py
extension_manager.fire(u'notify',
message=_(u'You have multiple unlinked loggers. This can lead to messy log files.')
Fired in: sketchpad_widget.py
extension_manager.fire(u'notify', message=notification,
category=u'info')
open_experiment
Fired in: qtopensesame.py
extension_manager.fire(u'open_experiment', path=path)
open_item
Fired in: qtitem.py
extension_manager.fire(u'open_item', name=self.name)
pause_experiment
Fired in: base_runner.py
extension_manager.fire(u'pause_experiment')
prepare_change_experiment
Fired in: general_properties.py
extension_manager.fire(u'prepare_change_experiment')
prepare_delete_item
Fired in: qtitem_store.py
extension_manager.fire(u'prepare_delete_item', name=name)
prepare_open_item
Fired in: qtitem.py
extension_manager.fire(u'prepare_open_item', name=self.name)
prepare_purge_unused_items
Fired in: unused_widget.py
extension_manager.fire(u'prepare_purge_unused_items')
prepare_regenerate
Fired in: qtopensesame.py
extension_manager.fire(u'prepare_regenerate')
prepare_rename_item
Fired in: qtitem_store.py
extension_manager.fire(u'prepare_rename_item', from_name=from_name,
to_name=to_name)
purge_unused_items
Fired in: unused_widget.py
extension_manager.fire(u'purge_unused_items')
pyqode_clear_breakpoints
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_clear_breakpoints')
pyqode_resume_auto_backend_restart
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_resume_auto_backend_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_resume_auto_backend_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_resume_auto_backend_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_resume_auto_backend_restart')
pyqode_select_indentation_mode
Fired in: menubar.py
extension_manager.fire('pyqode_select_indentation_mode')
pyqode_suspend_auto_backend_restart
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_suspend_auto_backend_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_suspend_auto_backend_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_suspend_auto_backend_restart')
Fired in: OpenSesameIDE.py
extension_manager.fire('pyqode_suspend_auto_backend_restart')
regenerate
Fired in: qtopensesame.py
extension_manager.fire(u'regenerate')
Fired in: qtopensesame.py
extension_manager.fire(u'regenerate')
register_editor
Fired in: qtplugin.py
extension_manager.fire(u'register_editor', editor=editor)
rename_item
Fired in: qtitem_store.py
extension_manager.fire(u'rename_item', from_name=from_name,
to_name=to_name)
resume_experiment
Fired in: base_runner.py
extension_manager.fire(u'resume_experiment')
run_experiment_canceled
Fired in: base_runner.py
extension_manager.fire('run_experiment_canceled')
save_experiment
Fired in: qtopensesame.py
extension_manager.fire(u'save_experiment', path=self.current_path)
startup
Fired in: qtopensesame.py
extension_manager.fire(u'startup')
unregister_editor
Fired in: OpenSesameIDE.py
extension_manager.fire('unregister_editor', editor=editor)