Difference between revisions of "PluginArchitecture"

From PyMOLWiki
Jump to: navigation, search
(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 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:

  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