Jump to content

PluginArchitecture: Difference between revisions

From PyMOL Wiki
Created page with 'This page concerns the development for new PyMOL Plugin Architecture. We are requesting ideas, code, etc on how to best implement a successful plug in system. = Review of Curre…'
 
document current architecture
 
(20 intermediate revisions by 4 users not shown)
Line 1: Line 1:
This page concerns the development for new PyMOL Plugin Architecture. We are requesting ideas, code, etc on how to best implement a successful plug in system.
This page describes PyMOL's plugin architechture since version 1.5.0.6.


= Review of Current Plugin System =
== API Entry Points ==


= Ideas/Features for the New Plugin System =
A plugin is a Python module which uses PyMOL's API. The following entrypoints add functionality to PyMOL:


= Liked Plugin Systems =
# [[extend|<code>pymol.cmd.extend(func)</code>]] registers a function as a PyMOL command
* [https://addons.mozilla.org/en-US/developers FireFox Devel/Docs]
# <code>pymol.plugins.addmenuitemqt(label, callback)</code> adds a plugin menu item, should be called inside [[#__init__plugin__|<code>__init_plugin__</code>]]
* Google Chrome -- URL?
# [[#__init__plugin__|<code>MyPlugin.__init_plugin__(app)</code>]] is called during plugin initialization (if defined by the plugin)


= Disliked Plugin Systems =
== __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>).


= The Name =
=== Example for a PyQt5 GUI (PyMOL 2.x) ===
* Plugins, Plug-Ins?
* Add-ons?
* Extensions?


''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 ==
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">
MyPlugin/
├── data
│   ├── datasheet.txt
│   └── image.png
├── submodule1.py
├── submodule2.py
└── __init__.py (defines "__init_plugin__(app=None)" function)
</source>
They can be zipped (<code>.zip</code>) for distribution, the [[Plugin Manager]] handles the unzipping during installation.
<source lang="bash">
zip -r MyPlugin-1.0.zip MyPlugin
</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 17: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:

  1. pymol.cmd.extend(func) registers a function as a PyMOL command
  2. pymol.plugins.addmenuitemqt(label, callback) adds a plugin menu item, should be called inside __init_plugin__
  3. 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)

See Also