-
Notifications
You must be signed in to change notification settings - Fork 38
Plugins tutorial
This page gives a very brief introduction to the plugin interface. See plugin API documentation for full information.
An Enki plugin is a Python package, that implements a Plugin
class. If it is placed in the userplugins
directory it can be activated in the plugin manager. On Linux, macOS you will find this directory under /home/USERNAME/.config/enki/userplugins/
; on Windows you will find it under C:\Users\USERNAME\.config\enki\userplugins
. You can find the location of that directory in the Settings > Plugins.
(Enki has another plugin directory under enki/plugins
. Plugins placed there are always loaded on startup. In most cases, it is better to place plugins in the userplugins
directory. The enki/plugins
directory should only be used by Enki developers.)
At minimum the plugin needs the following attributes:
"""A docstring describing the plugin in one sentence"""
__pluginname__ = "PLUGINNAME"
__author__ = "AUTHOR"
__version__ = "VERSION"
class Plugin:
def __init__(self):
pass
def terminate:
pass
The Plugin
class needs the two methods defined, they are called when the plugin is loaded and unloaded, respectively.
Let's create our first plugin. This manual gives step-by-step instructions. The final code may be found at enki/example-plugin/helloworld.py in Enki's Git repository. If you want to test it quickly, just copy this file to userplugins
and activate the plugin under Settings > Plugins.
For creating the "Hello, world" plugin, go to Enki sources directory, and create a file helloworld.py
in the userplugins
directory with the next code:
"""A hello world plugin for Enki"""
from PyQt5.QtWidgets import QMessageBox
# core is main enki.core singleton. It is usually used for getting pointers to other singletons
from enki.core.core import core
__pluginname__ = "Hello World"
__author__ = "Hello Author"
__version__ = "0.0.1"
class Plugin:
"""During initialization, core imports all modules and packages in enki/plugins directory,
searches for Plugin class in every module and creates an instance
"""
def __init__(self):
QMessageBox.information(core.mainWindow(), "Hello, world", "Plugin loaded")
def terminate(self):
"""This method is called by core for each plugin during termination
"""
QMessageBox.information(core.mainWindow(), "Hello, world", "Plugin terminated")
Now activate the plugin under Settings > Plugins and see, if your plugin is loaded.
class Plugin:
def __init__(self):
self._addAction()
def _addAction(self):
"""Add action to main menu
This action uses embedded icons. You can find list of icons in icons/ directory at project root
"""
action = core.actionManager().addAction( "mHelp/aSayHello",
"Say Hello...",
QIcon(':enkiicons/enki.png'))
core.actionManager().setDefaultShortcut(action, "Ctrl+Alt+Shift+H")
action.triggered.connect(self._sayHello)
def _sayHello(self):
"""Handler for main menu action
"""
QMessageBox.information(core.mainWindow(), "Hello, world", "Menu action has been triggered!")
Don't forget to add import QIcon
at the top of the file.
Restart Enki and look, if you have a new action in the Help menu. You even might go to Settings > Application shortcuts and set a new shortcut for it.
import enki.widgets.dockwidget
class MyDock(enki.widgets.dockwidget.DockWidget):
def __init__(self):
enki.widgets.dockwidget.DockWidget.__init__(self,
core.mainWindow(),
"Hello dock",
QIcon(":enkiicons/help.png"),
"Alt+H")
self.label = QLabel("This is Hello World dock")
self.setWidget(self.label)
class Plugin:
def __init__(self):
self._createDock()
def _createDock(self):
"""Create dock widget and add it to main window
"""
self._dock = MyDock()
core.mainWindow().addDockWidget(Qt.RightDockWidgetArea, self._dock)
class Plugin:
def __init__(self):
self._readSettings()
def _readSettings(self):
"""Read settings from core configuration file
"""
if not "HelloWorld" in core.config(): # first start
core.config()["HelloWorld"] = {}
core.config()["HelloWorld"]["VeryImportantSetting"] = "the correct value"
self._dock.label.setText('Option value: %s' % core.config()["HelloWorld"]["VeryImportantSetting"])
def _writeSettings(self):
"""This method is never called.
Just an example implementation
"""
core.config()["HelloWorld"]["VeryImportantSetting"] = "new value"
# Don't forget to flush config!
# if settings has been edited with main settings dialogue, it will be flushed automatically
core.config().flush()
Here we dynamically add our option to the main configuration file during the first start.
You also can edit enki/config/enki.default.json
class Plugin:
def __init__(self):
core.workspace().currentDocumentChanged.connect(self._onDocumentChanged)
def _onDocumentChanged(self, old, new):
"""Current document has been changed. Let's notify the user
"""
if new is not None:
core.mainWindow().appendMessage("Current file is '%s'" % new.fileName(), 1000)
Check the API docs for other useful signals
from enki.core.uisettings import TextOption
class SettingsPage(QWidget):
"""Settings page for Hello World plugin
"""
def __init__(self, parent):
QWidget.__init__(self, parent)
self._layout = QHBoxLayout(self)
self._label = QLabel("Very important option", self)
self._layout.addWidget(self._label)
self.edit = QLineEdit(self)
self._layout.addWidget(self.edit)
class Plugin:
def __init__(self):
core.uiSettingsManager().dialogAccepted.connect(self._applySettings)
core.uiSettingsManager().aboutToExecute.connect(self._onSettingsDialogAboutToExecute)
def _applySettings(self):
"""Dialog has been accepted. Apply settings
"""
self._dock.label.setText('Option value: %s' % core.config()["HelloWorld"]["VeryImportantOption"])
def _onSettingsDialogAboutToExecute(self, dialog):
"""UI settings dialogue is about to execute.
Add own options
"""
page = SettingsPage(dialog)
dialog.appendPage(u"Hello World", page, QIcon(':/enkiicons/help.png'))
# Options
dialog.appendOption(TextOption(dialog, core.config(), "HelloWorld/VeryImportantOption", page.edit))
Now go to Edit > Settings > Hello World, edit the text and check, if it is updated on UI. Then restart Enki and check, if the new value has been loaded from settings.
Congratulations! We just have created an absolutely useless plugin. And you are ready to create something more valuable. Full plugin API documentation and Enki team will help you.
Read also about coding style and rules at the Hacking guide.