Difference between revisions of "PluginArchitecture"

From PyMOLWiki
Jump to navigation Jump to 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