Plugins Tutorial
This tutorial is about writing your own plugin for PyMOL 2.x.
See the plugins page for how to install and use exisiting plugins.
Writing Plugins: Learn By Example
This tutorial shows how to write a PyMOL plugin with PyQt. The full source of the demo plugin is available on github.
The demo plugin adds a dialog to render images at a custom resolution.
Plugin Files
We will create a plugin which consists of multiple files inside a directory:
pymol2-demo-plugin/
├── demowidget.ui
└── __init__.py (defines "__init_plugin__(app=None)" function)
Registering your Plugin
First you must add your plugin to the Plugins menu.
This is done in the __init_plugin__
function of your plugin.
A callback (here: run_plugin_gui
) is added.
# file pymol2-demo-plugin/__init__.py
def __init_plugin__(app=None):
from pymol.plugins import addmenuitemqt
addmenuitemqt('Demo "Render" Plugin', run_plugin_gui)
Legacy note: The __init_plugin__
function takes one argument, a reference to the main Tk app to support legacy plugins witten with Tkinter (unused with PyQt plugins).
Creating a GUI
The callback may do arbitrary stuff. Here we're going to create a dialog and show it to the user.
# global reference to avoid garbage collection of our dialog
dialog = None
def run_plugin_gui():
# pymol.Qt provides the PyQt5 interface, but may support PyQt4 and/or PySide as well
from pymol.Qt import QtWidgets
global dialog
if dialog is None:
# create a new (empty) Window
dialog = QtWidgets.QDialog()
# TODO: FILL DIALOG WITH WIDGETS HERE
dialog.show()
Filling the GUI with Widgets
The most convenient and maintainable way to create user interfaces with Qt is by using the Qt Designer. Follow these steps to get started:
- Create a new "Widget" form (New Form > templates/forms > Widget > Create)
- Drag widgets like "Push Button" or "Line Edit" into your form
- Name your widgets ("objectName" in the "Property Editor"), this name will become a Python variable in your code
- Save as a UI file (
*.ui
) inside thepymol2-demo-plugin
directory
PyMOL provides a utility function to load a UI file into a parent widget: pymol.Qt.utils.loadUi(filename, widget)
# filename of our UI file
uifile = os.path.join(os.path.dirname(__file__), 'demowidget.ui')
# load the UI file into our dialog
from pymol.Qt.utils import loadUi
form = loadUi(uifile, dialog)
Make Buttons do something
We need to connect the signals of those widgets we created with the Qt Designer, like our buttons' clicked
signal.
Our example has a "Ray" button (objectName=button_ray) that we'll connect to the run()
function.
def run():
# get form data
height = form.input_height.value()
# some debugging feedback
print('User entered height', height)
# TODO: DO SOMETHING WITH FORM DATA
form.button_ray.clicked.connect(run)
Deploy the final plugin
The pymol2-demo-plugin
directory can be zipped for deployment (see PluginArchitecture#More than one file per plugin).
Full Source
The full source of the demo plugin is available on github.
Extending Plugins to the Command Line
While not really applicable to our simple "Render" plugin (it only wraps existing ray
and png
commands), most plugins should also provide their functionality as new PyMOL commands using cmd.extend().