OpenSesame
Rapunzel Code Editor
DataMatrix
Support forum
Python Tutorials
MindProbe
OpenSesame videos
Python videos
Supported by 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 Supported by