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

Creando una extensión

¿Qué es una extensión de OpenSesame?

Las extensiones agregan funcionalidad arbitraria a la interfaz de usuario de OpenSesame. Por ejemplo, una extensión puede agregar una nueva entrada a la barra de herramientas principal o al menú. (Para agregar funcionalidad que se pueda utilizar en experimentos, necesita un plugin.)

Archivos relevantes

Una o más extensiones se agrupan en un paquete de extensión, que siempre es un subpaquete de opensesame_extensions (que a su vez es un llamado paquete de espacio de nombres implícito, pero ese es un detalle técnico que no es muy importante). Supongamos que su paquete de extensión se llama example y que contiene una única extensión (puede haber más) llamada example_extension. Esto correspondería a la siguiente estructura de archivos y carpetas:

opensesame_extensions/
    example/
        __init__.py               # puede estar vacío pero debe existir
        example_extension/
            __init__.py           # contiene información de extensión
            example_extension.py  # contiene clase de extensión

Información de extensión

La información de la extensión se define en el __init__.py del módulo de extensión, por lo que en nuestro ejemplo este es opensesesame_extensions/example/example_extension/__init__.py.

"""Una cadena de documentación con una descripción de la extensión"""

# Un nombre de icono estándar
# - <https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html>
icon = 'applications-accessories'
# La etiqueta y el tooltip se usan para crear la acción predeterminada, que es
# insertar en el menú y / o barra de herramientas (o ninguno)
label = "Extensión de ejemplo"
tooltip = "Ejemplo de información sobre herramientas"
menu = {
    "index": -1,
    "separator_before": True,
    "separator_after": True,
    "submenu": "Ejemplo"
}
toolbar = {
    "index": -1,
    "separator_before": True,
    "separator_after": True
}
# La configuración se almacena de forma persistente en el objeto cfg
settings = {
    "example_setting": "valor de ejemplo"
}

Una extensión puede aparecer en el menú o en la barra de herramientas principal de OpenSesame. Esto requiere que defina varios campos en __init__.py como se muestra arriba:

  • La label es el texto que aparecerá en el menú.
  • El icon es un nombre de icono compatible con freedesktop que especifica el icono que aparecerá en el menú y / o barra de herramientas.
  • El index indica la posición de la extensión en el menú / barra de herramientas, y funciona como un índice de list. Es decir, los valores negativos son relativos a la última entrada, donde -1 coloca su extensión al final.

Para que su extensión responda a la activación del menú / barra de herramientas, implemente el método activate() como se muestra a continuación en el código de extensión.

Escribiendo el código de extensión

El código principal de extensión se coloca en [extension_name].py. Este archivo generalmente contiene solo una clase llamada [ExtensionName].py, es decir, una clase con el equivalente CamelCase del nombre del plugin, que hereda libqtopensesame.extensions.BaseExtension. Entonces, una clase de extensión básica (no funcional) se ve así:

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


class ExampleExtension(BaseExtension):
    """Una extensión de ejemplo que enumera varios eventos comunes. El nombre de la clase
    debe ser la versión CamelCase del folder_name y file_name. Entonces, en
    este caso, tanto la carpeta de extensión (que es un paquete de Python) como el
    archivo .py (que es un módulo de Python) se llaman example_extension, mientras que
    la clase se llama ExampleExtension.
    """

    def activate(self):
        oslogger.debug('se activó la extensión example_extension')

    def event_save_experiment(self, path):
        oslogger.debug(f'Se disparó el evento: save_experiment(path={path})')

    # Vea el código fuente de example_extension para obtener más oyentes de eventos

Escuchar eventos

OpenSesame dispara eventos cuando ocurre algo importante. Por ejemplo, el evento save_experiment se dispara cuando se guarda un experimento. Para que su extensión escuche un evento, simplemente implemente un método con el nombre event_[nombre del evento] como se muestra arriba.

Tenga en cuenta que algunos eventos toman argumentos de palabras clave, como path en el caso de save_experiment. La firma de palabras clave de su función debe coincidir con la firma de palabras clave esperada. Consulte la descripción general de eventos a continuación para obtener una lista completa de eventos y palabras clave esperadas.

Creando un paquete y subiéndolo a pypi

Crear un paquete de extensión y cargarlo en pypi funciona de la misma manera que lo hace para los complementos:

Ejemplos

Para un ejemplo funcional, consulte:

Otros ejemplos se pueden encontrar en la carpeta opensesame_extensions del código fuente de OpenSesame:

Resumen de eventos

Esta descripción general enumera todos los eventos que se disparan en algún lugar del código, y que su extensión puede escuchar implementando las funciones event_[nombredelevento]() correspondientes.

cambio_experimento

Disparado en: general_properties.py

extension_manager.fire(u'cambio_experimento')

cambio_elemento

Disparado en: sequence.py

extension_manager.fire(u'cambio_elemento', nombre=self.name)

Disparado en: qtitem.py

extension_manager.fire(u'cambio_elemento', nombre=self.name)

Disparado en: loop.py

extension_manager.fire(u'cambio_elemento', nombre=self.name)

cerrar

Disparado en: qtopensesame.py

extension_manager.fire(u'cerrar')

eliminar_elemento

Disparado en: qtitem_store.py

extension_manager.fire(u'eliminar_elemento', nombre=nombre)

latido_corazon

Disparado en: multiprocess_runner.py

extension_manager.fire(u'latido_corazon')

ide_saltar_a_linea

Disparado en: SymbolSelector.py

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

Disparado en: OpenSesameIDE.py

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

ide_nuevo_archivo

Disparado en: JupyterNotebook.py

extension_manager.fire(u'ide_nuevo_archivo', fuente=code, ext=ext)

ide_guardar_archivo_actual

Disparado en: OpenSesameIDE.py

extension_manager.fire('ide_guardar_archivo_actual')

deteccion_anotaciones_imagen

Disparado en: JupyterNotebook.py

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

excepcion_jupyter_ocurrida

Disparado en: transparent_jupyter_widget.py

extension_manager.fire('excepcion_jupyter_ocurrida')

finalizacion_ejecucion_jupyter

Disparado en: transparent_jupyter_widget.py

extension_manager.fire('finalizacion_ejecucion_jupyter')

resultado_texto_ejecucion_jupyter

Disparado en: transparent_jupyter_widget.py

extension_manager.fire('resultado_texto_ejecucion_jupyter', texto=texto)

inicio_ejecucion_jupyter

Disparado en: transparent_jupyter_widget.py

extension_manager.fire('inicio_ejecucion_jupyter')

interrupcion_jupyter

Disparado en: OpenSesameIDE.py

extension_manager.fire(u'interrupcion_jupyter')

reiniciar_jupyter

Disparado en: console_bridge.py

extension_manager.fire(u'jupyter_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire(u'jupyter_restart')

jupyter_run_code

Disparado en: menubar.py

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

jupyter_run_system_command

Disparado en: JupyterNotebook.py

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

jupyter_show_prompt

Disparado en: console_bridge.py

extension_manager.fire(u'jupyter_show_prompt')

jupyter_write

Disparado en: console_bridge.py

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

new_item

Disparado en: tree_overview.py

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

new_linked_copy

Disparado en: tree_overview.py

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

notify

Disparado en: sequence.py

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

Disparado en: 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.')

Disparado en: qtitem.py

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

Disparado en: 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.')

Disparado en: logger.py

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

Disparado en: sketchpad_widget.py

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

open_experiment

Disparado en: qtopensesame.py

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

open_item

Disparado en: qtitem.py

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

pause_experiment

Disparado en: base_runner.py

extension_manager.fire(u'pause_experiment')

prepare_change_experiment

Disparado en: general_properties.py

extension_manager.fire(u'prepare_change_experiment')

prepare_delete_item

Disparado en: qtitem_store.py

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

prepare_open_item

Disparado en: qtitem.py

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

prepare_purge_unused_items

Disparado en: unused_widget.py

extension_manager.fire(u'prepare_purge_unused_items')

prepare_regenerate

Disparado en: qtopensesame.py

extension_manager.fire(u'prepare_regenerate')

prepare_rename_item

Disparado en: qtitem_store.py

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

purge_unused_items

Disparado en: unused_widget.py

extension_manager.fire(u'purge_unused_items')

pyqode_clear_breakpoints

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_clear_breakpoints')

pyqode_resume_auto_backend_restart

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_resume_auto_backend_restart')

pyqode_select_indentation_mode

Disparado en: menubar.py

extension_manager.fire('pyqode_select_indentation_mode')

pyqode_suspend_auto_backend_restart

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

Disparado en: OpenSesameIDE.py

extension_manager.fire('pyqode_suspend_auto_backend_restart')

regenerate

Disparado en: qtopensesame.py

extension_manager.fire(u'regenerate')

Disparado en: qtopensesame.py

extension_manager.fire(u'regenerate')

register_editor

Disparado en: qtplugin.py

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

rename_item

Disparado en: qtitem_store.py

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

resume_experiment

Disparado en: base_runner.py

extension_manager.fire(u'resume_experiment')

run_experiment_canceled

Disparado en: base_runner.py

extension_manager.fire('run_experiment_canceled')

save_experiment

Disparado en: qtopensesame.py

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

startup

Disparado en: qtopensesame.py

extension_manager.fire(u'startup')

unregister_editor

Disparado en: OpenSesameIDE.py

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