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
[edit]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
[edit]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
[edit]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
[edit]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
[edit]
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-plugindirectory
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
[edit]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
[edit]The pymol2-demo-plugin directory can be zipped for deployment (see PluginArchitecture#More than one file per plugin).
Full Source
[edit]The full source of the demo plugin is available on github.
Extending Plugins to the Command Line
[edit]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().