PluginArchitecture: Difference between revisions
(document current architecture) |
|||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
This page | This page describes PyMOL's plugin architechture since version 1.5.0.6. | ||
= | == API Entry Points == | ||
A | A plugin is a Python module which uses PyMOL's API. The following entrypoints add functionality to PyMOL: | ||
# [[extend|<code>pymol.cmd.extend(func)</code>]] registers a function as a PyMOL command | |||
# <code>pymol.plugins.addmenuitemqt(label, callback)</code> adds a plugin menu item, should be called inside [[#__init__plugin__|<code>__init_plugin__</code>]] | |||
# [[#__init__plugin__|<code>MyPlugin.__init_plugin__(app)</code>]] is called during plugin initialization (if defined by the plugin) | |||
= | == __init_plugin__ == | ||
A plugin can implement an <code>__init_plugin__(app)</code> function (''previously <code>__init__</code>, deprecated'') which is called during plugin initialization. It is passed an object which is compatible with the legacy <code>PMGApp</code> instance and provides access to the Tkinter parent (<code>app.root</code>). | |||
=== Example for a PyQt5 GUI (PyMOL 2.x) === | |||
''See also the [[Plugins Tutorial]]'' | |||
<syntaxhighlight lang="python"> | |||
def __init_plugin__(app=None): | |||
from pymol.plugins import addmenuitemqt | |||
addmenuitemqt('My Qt Plugin', myqtdialog) | |||
def myqtdialog(): | |||
from pymol.Qt import QtWidgets | |||
QtWidgets.QMessageBox.information(None, 'My Plugin Title', 'Hello World') | |||
</syntaxhighlight> | |||
=== Example for a legacy Tkinter GUI (PyMOL 1.x) === | |||
It is important that all Tkinter objects are created with the <code>app.root</code> parent, otherwise legacy plugins won't work in PyMOL 2.0. | |||
<syntaxhighlight lang="python"> | |||
def __init_plugin__(app): | |||
app.menuBar.addmenuitem('Plugin', 'command', | |||
label='My Tk Plugin', | |||
command=lambda: mytkdialog(app.root)) | |||
def mytkdialog(parent): | |||
try: | |||
import tkMessageBox # Python 2 | |||
except ImportError: | |||
import tkinter.messagebox as tkMessageBox # Python 3 | |||
tkMessageBox.showinfo(parent=parent, title='My Plugin Title', message='Hello World') | |||
</syntaxhighlight> | |||
== More than one file per plugin == | == More than one file per plugin == | ||
Plugins can be either a single Python file, or a directory with an <code>__init__.py</code> file. | |||
'''Single file layout:''' | |||
<syntaxhighlight lang="python"> | |||
MyPlugin.py (defines "__init_plugin__(app=None)" function) | |||
</syntaxhighlight> | |||
'''Directory layout:''' | |||
<source lang="Python"> | <source lang="Python"> | ||
MyPlugin/ | |||
├── data | |||
│ ├── datasheet.txt | |||
│ └── image.png | |||
├── submodule1.py | |||
├── submodule2.py | |||
└── __init__.py (defines "__init_plugin__(app=None)" function) | |||
</source> | </source> | ||
They can be zipped (<code>.zip</code>) for distribution, the [[Plugin Manager]] handles the unzipping during installation. | |||
<source lang="bash"> | <source lang="bash"> | ||
zip | zip -r MyPlugin-1.0.zip MyPlugin | ||
</source> | </source> | ||
== Config files == | |||
< | PyMOL offers a basic API to store custom settings in <code>~/.pymolpluginsrc.py</code>. | ||
Only basic types (<code>str</code>, | |||
<code>int</code>, | |||
<code>float</code>, | |||
</ | <code>list</code>, | ||
<code>tuple</code>, | |||
<code>dict</code>, | |||
etc.) | |||
are suppored (those who produce executable code with <code>repr()</code>). | |||
'''Store:''' | |||
<syntaxhighlight lang="python"> | |||
pymol.plugins.pref_set(key, value) | |||
# needed if pymol.plugins.pref_get("instantsave") == False | |||
pymol.plugins.pref_save() | |||
</syntaxhighlight> | |||
'''Load:''' | |||
<syntaxhighlight lang="python"> | |||
value = pymol.plugins.pref_get(key, default=None) | |||
</syntaxhighlight> | |||
'''Example:''' | |||
<syntaxhighlight lang="python"> | |||
apbsbinary = pymol.plugins.pref_get("APBS_BINARY_LOCATION", "/usr/bin/apbs") | |||
</syntaxhighlight> | |||
= | == PyMOL OS Fellowship Project 2011/2012 == | ||
[[User:Speleo3|Thomas Holder]] was working on the new plugin system as part of his [http://pymol.org/fellowship 2011-2012 Fellowship]. The improvements were incorporated into PyMOL 1.5.0.5. | |||
* graphical [[Plugin Manager]] | |||
* [ | * multiple files per plugin/module (see [[#More than one file per plugin]]) | ||
* | * user plugin directory | ||
* [ | * rarely used plugins can be disabled for better performance and enabled on demand | ||
* metadata support (version, author, description, citation, tags, ...) | |||
* install from online repositories | |||
* settings API for plugins (see [[#Config files]]) | |||
= | == See Also == | ||
* [[Plugin Manager]] | |||
* [[Plugins Tutorial]] | |||
* [[Plugins]] | |||
[[Category:Plugins]] | |||
[[Category:Development]] | [[Category:Development]] | ||
[[Category:Developers]] | [[Category:Developers]] |
Latest revision as of 13:43, 13 November 2018
This page describes PyMOL's plugin architechture since version 1.5.0.6.
API Entry Points
A plugin is a Python module which uses PyMOL's API. The following entrypoints add functionality to PyMOL:
pymol.cmd.extend(func)
registers a function as a PyMOL commandpymol.plugins.addmenuitemqt(label, callback)
adds a plugin menu item, should be called inside__init_plugin__
MyPlugin.__init_plugin__(app)
is called during plugin initialization (if defined by the plugin)
__init_plugin__
A plugin can implement an __init_plugin__(app)
function (previously __init__
, deprecated) which is called during plugin initialization. It is passed an object which is compatible with the legacy PMGApp
instance and provides access to the Tkinter parent (app.root
).
Example for a PyQt5 GUI (PyMOL 2.x)
See also the Plugins Tutorial
def __init_plugin__(app=None):
from pymol.plugins import addmenuitemqt
addmenuitemqt('My Qt Plugin', myqtdialog)
def myqtdialog():
from pymol.Qt import QtWidgets
QtWidgets.QMessageBox.information(None, 'My Plugin Title', 'Hello World')
Example for a legacy Tkinter GUI (PyMOL 1.x)
It is important that all Tkinter objects are created with the app.root
parent, otherwise legacy plugins won't work in PyMOL 2.0.
def __init_plugin__(app):
app.menuBar.addmenuitem('Plugin', 'command',
label='My Tk Plugin',
command=lambda: mytkdialog(app.root))
def mytkdialog(parent):
try:
import tkMessageBox # Python 2
except ImportError:
import tkinter.messagebox as tkMessageBox # Python 3
tkMessageBox.showinfo(parent=parent, title='My Plugin Title', message='Hello World')
More than one file per plugin
Plugins can be either a single Python file, or a directory with an __init__.py
file.
Single file layout:
MyPlugin.py (defines "__init_plugin__(app=None)" function)
Directory layout:
MyPlugin/
├── data
│ ├── datasheet.txt
│ └── image.png
├── submodule1.py
├── submodule2.py
└── __init__.py (defines "__init_plugin__(app=None)" function)
They can be zipped (.zip
) for distribution, the Plugin Manager handles the unzipping during installation.
zip -r MyPlugin-1.0.zip MyPlugin
Config files
PyMOL offers a basic API to store custom settings in ~/.pymolpluginsrc.py
.
Only basic types (str
,
int
,
float
,
list
,
tuple
,
dict
,
etc.)
are suppored (those who produce executable code with repr()
).
Store:
pymol.plugins.pref_set(key, value)
# needed if pymol.plugins.pref_get("instantsave") == False
pymol.plugins.pref_save()
Load:
value = pymol.plugins.pref_get(key, default=None)
Example:
apbsbinary = pymol.plugins.pref_get("APBS_BINARY_LOCATION", "/usr/bin/apbs")
PyMOL OS Fellowship Project 2011/2012
Thomas Holder was working on the new plugin system as part of his 2011-2012 Fellowship. The improvements were incorporated into PyMOL 1.5.0.5.
- graphical Plugin Manager
- multiple files per plugin/module (see #More than one file per plugin)
- user plugin directory
- rarely used plugins can be disabled for better performance and enabled on demand
- metadata support (version, author, description, citation, tags, ...)
- install from online repositories
- settings API for plugins (see #Config files)