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.
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 the
PyMOL provides a utility function to load a UI file into a parent 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'
Our example has a "Ray" button (objectName=button_ray) that we'll connect to the
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
pymol2-demo-plugin directory can be zipped for deployment (see PluginArchitecture#More than one file per plugin).
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
png commands), most plugins should also provide their functionality as new PyMOL commands using cmd.extend().