OpenSesame
Rapunzel Code Editor
DataMatrix
Support forum
Python Tutorials
MindProbe
Supported by

Eine Erweiterung erstellen

Was ist eine OpenSesame-Erweiterung?

Erweiterungen fügen der OpenSesame-Benutzeroberfläche beliebige Funktionen hinzu. Zum Beispiel kann eine Erweiterung einen neuen Eintrag in der Hauptwerkzeugleiste oder der Menüleiste hinzufügen. (Um Funktionen hinzuzufügen, die Sie in Experimenten verwenden können, benötigen Sie ein Plugin.)

Relevante Dateien

Eine oder mehrere Erweiterungen werden in einem Erweiterungspaket zusammengefasst, das immer ein Unterpaket von opensesame_extensions ist (das selbst ein sogenanntes implizites Namespace-Paket ist, aber das ist ein technisches Detail, das nicht sehr wichtig ist). Nehmen wir an, Ihr Erweiterungspaket heißt example, und es enthält eine einzelne Erweiterung (es können mehr sein) namens example_extension. Dies würde der folgenden Datei- und Verzeichnisstruktur entsprechen:

opensesame_extensions/
    example/
        __init__.py               # kann leer sein, muss aber vorhanden sein
        example_extension/
            __init__.py           # enthält Erweiterungsinformationen
            example_extension.py  # enthält Erweiterungsklasse

Erweiterungsinformationen

Erweiterungsinformationen sind in der __init__.py des Erweiterungsmoduls definiert, also in unserem Beispiel ist das opensesesame_extensions/example/example_extension/__init__.py.

"""Ein Docstring mit einer Beschreibung der Erweiterung"""

# Ein Standard-Icon-Name
# - <https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html>
icon = 'applications-accessories'
# Das Label und der Tooltip werden verwendet, um die Standardaktion zu erstellen, die
# im Menü und/oder der Werkzeugleiste (oder keiner von beiden) eingefügt wird
label = "Beispiel-Erweiterung"
tooltip = "Beispiel-Tooltip"
menu = {
    "index": -1,
    "separator_before": True,
    "separator_after": True,
    "submenu": "Beispiel"
}
toolbar = {
    "index": -1,
    "separator_before": True,
    "separator_after": True
}
# Einstellungen werden dauerhaft im cfg-Objekt gespeichert
settings = {
    "example_setting": "example value"
}

Eine Erweiterung kann im Menü oder in der Hauptwerkzeugleiste von OpenSesame erscheinen. Dazu müssen Sie mehrere Felder in __init__.py definieren, wie oben gezeigt:

  • Das label ist der Text, der im Menü erscheinen wird.
  • Das icon ist ein freedesktop-konformer Icon-Name, der das Icon angibt, das im Menü und/oder in der Werkzeugleiste erscheinen wird.
  • Der index gibt die Position der Erweiterung im Menü/der Werkzeugleiste an und funktioniert wie ein list-Index. Das heißt, negative Werte beziehen sich auf den letzten Eintrag, wobei -1 Ihre Erweiterung am Ende platziert.

Um Ihre Erweiterung auf Menü-/Werkzeugleistenaktivierung zu reagieren, implementieren Sie die activate()-Methode, wie unten in dem Erweiterungscode gezeigt.

Schreiben des Erweiterungscodes

Der Haupterweiterungscode befindet sich in [extension_name].py. Diese Datei enthält in der Regel nur eine einzige Klasse mit dem Namen [ExtensionName].py, also eine Klasse mit dem CamelCase-Äquivalent des Plugin-Namens, die von libqtopensesame.extensions.BaseExtension erbt. Eine grundlegende (nicht funktionale) Erweiterungsklasse sieht also so aus:

from libopensesame.py3compat import *
from libopensesame.oslogging import oslogger
from libqtopensesame.extensions import BaseExtension


class ExampleExtension(BaseExtension):
    """Eine Beispiel-Erweiterung, die mehrere häufige Ereignisse auflistet. Der Klassenname
    sollte die CamelCase-Version des folder_name und file_name sein. Also in
    diesem Fall sind sowohl der Erweiterungsordner (der ein Python-Paket ist) als auch die
    .py-Datei (die ein Python-Modul ist) mit example_extension benannt, während
    die Klasse ExampleExtension genannt ist.
    """

    def activate(self):
        oslogger.debug('example_extension Erweiterung aktiviert')

    def event_save_experiment(self, path):
        oslogger.debug(f'Ereignis ausgelöst: save_experiment(path={path})')

    # Weitere Ereignislistener finden Sie im Beispiel-Code von example_extension

Lauschen auf Ereignisse

OpenSesame löst Ereignisse aus, wenn etwas Wichtiges passiert. Zum Beispiel wird das Ereignis save_experiment ausgelöst, wenn ein Experiment gespeichert wird. Um Ihre Erweiterung auf ein Ereignis hören zu lassen, implementieren Sie einfach eine Methode mit dem Namen event_[event name], wie oben gezeigt.

Beachten Sie, dass einige Ereignisse Schlüsselwortargumente verwenden, wie path im Falle von save_experiment. Die Schlüsselwortsygnatur Ihrer Funktion muss der erwarteten Schlüsselwortsygnatur entsprechen. Siehe die Ereignisübersicht unten für eine vollständige Liste der Ereignisse und erwarteten Schlüsselwörter.

Ein Paket erstellen und auf pypi hochladen

Ein Extension-Paket erstellen und auf pypi hochladen funktioniert genauso wie für Plugins:

Beispiele

Für ein funktionierendes Beispiel siehe:

Weitere Beispiele finden Sie im Ordner opensesame_extensions des OpenSesame-Quellcodes:

Ereignisübersicht

In dieser Übersicht sind alle Ereignisse aufgeführt, die irgendwo im Code ausgelöst werden und auf die Ihre Erweiterung daher hören kann, indem sie die entsprechenden event_[eventname]() Funktionen implementiert.

change_experiment

Ausgelöst in: general_properties.py

extension_manager.fire(u'change_experiment')

change_item

Ausgelöst in: sequence.py

extension_manager.fire(u'change_item', name=self.name)

Ausgelöst in: qtitem.py

extension_manager.fire(u'change_item', name=self.name)

Ausgelöst in: loop.py

extension_manager.fire(u'change_item', name=self.name)

close

Ausgelöst in: qtopensesame.py

extension_manager.fire(u'close')

delete_item

Ausgelöst in: qtitem_store.py

extension_manager.fire(u'delete_item', name=name)

heartbeat

Ausgelöst in: multiprocess_runner.py

extension_manager.fire(u'heartbeat')

ide_jump_to_line

Ausgelöst in: SymbolSelector.py

extension_manager.fire('ide_jump_to_line', lineno=lineno)

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('ide_jump_to_line', lineno=line_number)

ide_new_file

Ausgelöst in: JupyterNotebook.py

extension_manager.fire(u'ide_new_file', source=code, ext=ext)

ide_save_current_file

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('ide_save_current_file')

image_annotations_detect

Ausgelöst in: JupyterNotebook.py

extension_manager.fire(u'image_annotations_detect', code=code)

jupyter_exception_occurred

Ausgelöst in: transparent_jupyter_widget.py

extension_manager.fire('jupyter_exception_occurred')

jupyter_execute_finished

Ausgelöst in: transparent_jupyter_widget.py

extension_manager.fire('jupyter_execute_finished')

jupyter_execute_result_text

Ausgelöst in: transparent_jupyter_widget.py

extension_manager.fire('jupyter_execute_result_text', text=text)

jupyter_execute_start

Ausgelöst in: transparent_jupyter_widget.py

extension_manager.fire('jupyter_execute_start')

jupyter_interrupt

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire(u'jupyter_interrupt')

jupyter_restart

Ausgelöst in: console_bridge.py

extension_manager.fire(u'jupyter_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire(u'jupyter_restart')

jupyter_run_code

Ausgelöst in: menubar.py

extension_manager.fire('jupyter_run_code',
                                                     code=command)

jupyter_run_system_command

Ausgelöst in: JupyterNotebook.py

extension_manager.fire('jupyter_run_system_command', cmd=cmd)

jupyter_show_prompt

Ausgelöst in: console_bridge.py

extension_manager.fire(u'jupyter_show_prompt')

jupyter_write

Ausgelöst in: console_bridge.py

extension_manager.fire(u'jupyter_write', msg=s)

new_item

Ausgelöst in: tree_overview.py

extension_manager.fire(u'new_item', name=item.name,
                _type=item.item_type)

new_linked_copy

Ausgelöst in: tree_overview.py

extension_manager.fire('new_linked_copy', name=item_name)

notify

Ausgelöst in: sequence.py

extension_manager.fire(u'notify',
                    message=_(u'Sequence contains non-existing item: %s')

Ausgelöst 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.')

Ausgelöst in: qtitem.py

extension_manager.fire(u'notify',
                        message=_(u'"%s" is defined using '
                        'variables and can only be edited through the '
                        'script.')

Ausgelöst 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.')

Ausgelöst in: logger.py

extension_manager.fire(u'notify',
                    message=_(u'You have multiple unlinked loggers. This can lead to messy log files.')

Ausgelöst in: sketchpad_widget.py

extension_manager.fire(u'notify', message=notification,
                category=u'info')

open_experiment

Ausgelöst in: qtopensesame.py

extension_manager.fire(u'open_experiment', path=path)

open_item

Ausgelöst in: qtitem.py

extension_manager.fire(u'open_item', name=self.name)

pause_experiment

Ausgelöst in: base_runner.py

extension_manager.fire(u'pause_experiment')

prepare_change_experiment

Ausgelöst in: general_properties.py

extension_manager.fire(u'prepare_change_experiment')

prepare_delete_item

Ausgelöst in: qtitem_store.py

extension_manager.fire(u'prepare_delete_item', name=name)

prepare_open_item

Ausgelöst in: qtitem.py

extension_manager.fire(u'prepare_open_item', name=self.name)

prepare_purge_unused_items

Ausgelöst in: unused_widget.py

extension_manager.fire(u'prepare_purge_unused_items')

prepare_regenerate

Ausgelöst in: qtopensesame.py

extension_manager.fire(u'prepare_regenerate')

prepare_rename_item

Ausgelöst in: qtitem_store.py

extension_manager.fire(u'prepare_rename_item', from_name=from_name,
            to_name=to_name)

purge_unused_items

Ausgelöst in: unused_widget.py

extension_manager.fire(u'purge_unused_items')

pyqode_clear_breakpoints

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_clear_breakpoints')

pyqode_resume_auto_backend_restart

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

pyqode_select_indentation_mode

Ausgelöst in: menubar.py

extension_manager.fire('pyqode_select_indentation_mode')

pyqode_suspend_auto_backend_restart

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

Ausgelöst in: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

regenerate

Ausgelöst in: qtopensesame.py

extension_manager.fire(u'regenerate')

Ausgeführt in: qtopensesame.py

extension_manager.fire(u'neu_generieren')

register_editor

Ausgeführt in: qtplugin.py

extension_manager.fire(u'register_editor', editor=editor)

rename_item

Ausgeführt in: qtitem_store.py

extension_manager.fire(u'benenne_item_um', from_name=from_name,
            to_name=to_name)

resume_experiment

Ausgeführt in: base_runner.py

extension_manager.fire(u'fortsetzen_experiment')

run_experiment_canceled

Ausgeführt in: base_runner.py

extension_manager.fire('lauf_experiment_abgebrochen')

save_experiment

Ausgeführt in: qtopensesame.py

extension_manager.fire(u'speichern_experiment', path=self.current_path)

startup

Ausgeführt in: qtopensesame.py

extension_manager.fire(u'startup')

unregister_editor

Ausgeführt in: OpenSesameIDE.py

extension_manager.fire('editor_abmelden', editor=editor)
Supported by