Development:Plugin Developers Guide
From OpenLP
Contents |
Plugin Architecture
Directory Structure
All plugins need to have the same directory structure. The Songs plugin's directory structure is illustrated below as an example:
Each plugin has a directory within the openlp.org "plugins" directory. This directory is named the same as the plugin's name. Within the name directory there will be a nameplugin.py file which contains the NamePlugin class. This plugin class extends the builtin openlp.org Plugin class. This provides your plugin with a number of key methods to override.
Naming Conventions
- All code should follow the Python syntax guidelines, known as PEP 8.
- The recommended naming convention for plugins is the plural of the object it provides (e.g. Songs).
- Plugin names should not contain spaces.
Base Plugin Class
The base Plugin class is shown below, with all the hooks that you need to provide if you want to make use of its functionality.
Note: This is a cut down version of the Plugin class.
class Plugin(object):
def __init__(self, name=None, version=None):
if name is not None:
self.name = name
else:self.name = 'Plugin'
if version is not None:
self.version = version
self.icon = None
self.config = PluginConfig(self.name)
self.weight = 0
# Set up loggingself.log = logging.getLogger(self.name)
def check_pre_conditions(self):
return True
def get_media_manager_item(self):
passdef add_import_menu_item(self, import_menu):
passdef add_export_menu_item(self, export_menu):
passdef get_settings_tab(self):
passdef add_to_menu(self, menubar):
passdef handle_event(self, event):
passdef about(self):
passdef save(self, data):
passdef load(self, string):
passdef render(self, theme, screen=None):
passdef initalise(self):
pass
Developing An Example Plugin
Starting The Plugin
So let's start by building a very basic plugin, one that will add an item to the media manager, which will have a toolbar, and one button on the toolbar that pops up a "Hello World" message (we had to get the "Hello World" in *somewhere* ;-) ).
- First create a directory in the
pluginsdirectory. Let's call ithelloworld. - Create a
__init__.pyfile in that directory. This converts the directory into a Python module, so that openlp.org can load your plugin. - Create a file named
helloworldplugin.py.
The Plugin Code
Next we'll need some code in that new plugin file. Copy and paste the following code into the new file. Don't forget to create yourself a little icon, and update the path to the icon to match your icon's path.
import os
from openlp.core.lib import Plugin, MediaManagerItem
class HelloWorldPlugin(Plugin):
def __init__(self):
# Call the parent constructorPlugin.__init__(self, 'HelloWorld', '1.9.0')
# Create the plugin iconself.icon = QtGui.QIcon()
self.icon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(
os.path.join(os.path.asbpath(os.path.basename(__file__)),
'resources', 'images', 'helloworld.png'))), QtGui.QIcon.Normal,
QtGui.QIcon.Off)
def get_media_manager_item(self):
# Create the MediaManagerItem objectself.MediaManagerItem = MediaManagerItem(self.icon, 'Hello World')
# Add a toolbarself.MediaManagerItem.addToolbar()
# Create button for the toolbarself.MediaManagerItem.addToolbarButton('Hello World', 'Says, "Hello World"',
os.path.join(os.path.asbpath(os.path.basename(__file__)), 'resources',
'images', 'helloworld.png'), self.onHelloWorldClick, 'HelloWorldItem')
def onHelloWorldClick(self):
QtGui.QMessageBox.information(None, 'Hello World!',
'This is just a little message box to say, "Hello World!"',QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok)
An Explanation
So how does the plugin work?
- Import the
osmodule for use with file paths in our plugin. - Import the
Pluginclasses, so that we can use them in our code. - Make our class descend from the
Pluginclass. - Create a constructor:
- Call the
Pluginclass's constructor to set up some basic information. - Load an icon for our plugin into the plugin's
iconproperty.
- Call the
- Implement the
get_media_manager_item()hook:- Create an instance of the
XXXManagerItemclass.
- Create an instance of the
- Implement the
get_settings_tab()hook:- Create an instance of the
XXXTabclass.
- Create an instance of the
- Add a toolbar to the item.
- Add a button to the toolbar, with the following parameters:
- Caption
- Tooltip
- Icon
- Slot (a function to react to the
triggered()signal/event) - Object name
- Create the Slot with an applicable action (in our case, showing a "Hello World" dialog).
Plugin Hooks
Hooks are special Python methods that are executed at various points throughout openlp.org. The list below shows all of these hooks, when each of them is activated, and what each one of them is supposed to do.
about()
Show a dialog when the user clicks on the 'About' button in the plugin manager.
save(media_item)
A plugin's media item is passed to this function, which should return a ServiceItem object which can be written to the service file.
load(service_item)
A ServiceItem object from the service file is passed in. This function parses and sets up an instance of the plugin's media item for use within the plugin.
render(screen, service_item, theme)
Render the screenth screenful of the service_item (a ServiceItem object), using theme settings in theme.
What is screen? An object, a number, a canvas?
get_media_manager_item()
Construct a MediaManagerItem object with all the buttons and things you need, and return it for integration into openlp.org's Media Manager.
Given the import menu item, add an item to the Import menu.
Given the export menu item, add an item to the Export menu.
Add menu items to the menu, given the menubar.
handle_event(event)
Handle the event contained in the event object.
initialise()
Called by the plugin manager to setup any additional features on creation.
Configuration
Configuration File
Each plugin comes with a built-in self.config object, which reads and writes to a plugin-specific section of the openlp.org configuration file. On Linux, Mac OS X, and other Unix-like operating systems, this configuration file can be found in the following location: ~/.openlp/openlp.conf. On Windows, this file is found in: C:\Documents and Settings\username\Application Data\.openlp\openlp.conf.
For example:
[<pluginName>]
last dir = /home/<name>/somedirectory
This is location where the last file loaded into the plugin came from.
list count = 2
This is a count of how many files are to be loaded into the plugin's list
list item 1 = /home/<name>/somedirectory/somefile.xyz
The location and name of the file to be loaded into the plugin's list.
PluginUtls Class
A PluginUtils class can be added the the Plugin's definition to provide access to a number of utility methods to reduce code duplication. These methods will return empty lists or strings if the configuration tags have not been defined.
Defines a Context menu item with icon 'icon' and text 'text'. Which is connected to list 'base' and will trigger action 'slot' when selected.
add_to_context_separator(self, base)
Defines a Context separator item for the context menu
_load_display_list()
Reads the configuration data and returns a list of items to the added to the display list.
_save_display_list(self, displaylist)
Takes a display list 'displaylist' and saves the details in the configuration file allowing the list to be reloaded later.
_get_last_dir
Reads the configuration file to provide the last directory used by the plugin
_save_last_directory(self, filename)
Extracts the directory part of the filename and saves that in the configuration file
Plugin Dialogs
Media Items
Settings Tabs
The Settings dialog calls each plugin using the get_settings_tab method. The plugin is able to create a tab on the Settings Dialog by returning a class extending SettingsTab.
class HelloWorldTab(SettingsTab):
def __init__(self):
HelloWorldTab.__init__(self, u'Hello World')
def setupUi(self):
self.setObjectName(u'HelloWorldTab')
def retranslateUi(self):
passdef load(self):
passdef save(self):
pass
