In two previous articles (one one using Eclipse to build QGIS, and
the other on using Eclipse as a Django development platform), I
mentioned I would delve a little into using the Eclipse environment as a
platform for QGIS Plugin Development. In particular we are interested in
using Eclipse as a remote debugging platform. What does that mean? It
means that Eclipse/PyDev will be able to attach itself to your plugin
running withing QGIS and then step through the plugin code line by line,
inspect variables and so on. This is incredibly useful as it allows you
to break away from the very bad 'code, launch plugin, hope for the best'
development process to one which is much more rigourous and time
effecient. This article describes the process I followed to get
everything set up for remote debugging with Eclipse/PyDev effectively. I
also throw in a couple of other tips on how to use PyDev as an effective
plugin development platform. Read more after the break below....
Initial Setup
So if you haven't already followed the steps for setting up PyDev from
my previous article, you should do that first. The procedures
described here will probably work equally well on Windows and OSX,
though I haven't tested them. Ok so let's dive in! First thing you need
to do is have a plugin to test with. In my case, I simply used the
plugin builder plugin (I know its a bit meta!) that Gary Sherman (master
of the QGIS universe) wrote in order to create a simple test plugin. To
install the plugin builder in QGIS go to Plugins -> Fetch Python
Plugins. Ensure that you have the QGIS Contributed Plugins Repository
enabled (the simplest way to do that is to use the 'Add 3rd Party
Repostiories' button under the Repositories tab). Now filter the
plugins list using the word 'Builder' and then install the Plugin
Builder plugin.
While you are at it, I also recommend installing the 'Plugin
reloader' plugin which allows you to reload a plugin when you have
made some code changes without reinstalling all of QGIS.
Create your plugin
Ok now the next step is to create a new plugin. If you have an existing
plugin that you want to work with, you can skip this step. First ensure
the plugin builder and reloader plugins are enabled (Plugins-> Manage
Plugins), then launch the plugin builder (Plugins -> Plugin Builder
-> Plugin Builder). Now fill in the blanks to create a new plugins -
you can change the details as needed.
When you are done, click ok and choose ${HOME}/.qgis/python/plugins as
the directory in which to save your plugin. Afterwards you should see a
report something like this:
Ok for now, we can close QGIS and jump over to Eclipse. Here is a
summary of the steps we will be following:
- Create a new PyDev project
- Setup some eclipse helpers to allow us to run pyuic4 and pyrcc4 from
within eclipse
- Add a remote breakpoint to the plugin
- Run the PyDev server
- Launch the plugin in QGIS
- Step through the code from in Eclipse
It's a few steps to follow, but you do it once and then forget about it
so let's dive in...
Create the PyDev project
In Eclipse do File -> New -> PyDev Project. In the dialog that
appears, fill in the blanks as in the screenshot below (adapting for
your system as needed).
Take special note of the fact that I have unticked 'Use default' and
instead pointed the project contents folder into my plugin folder
under ${HOME}/.qgis/python/plugins/RemoteDebuggerTest. Also note that
the Interpreter is set to 'Default' and the 'Don't configure python
path' option is set. Click next and then just accept the next screen.
Ok, now you should have the project listed in your project browser like
this:
Setup Eclipse Helpers
So one thing that you don't get out of the box with Eclipse PyDev is the
ability to compile Qt ui's (user interface files) and Qt rcc's (resource
files). There are two command line tools that usually do this for you -
pyuic4 and pyrcc4. These tools need to be run on any ui and rcc files
you may have whenever they are changed. Running these tools will
generate python code from the xml documents contained in these files.
When you use the plugin builder to generate your plugin, it also creates
a makefile which will build these for you, so under Linux, the quickest
way to build them is to create an Eclipse helper to launch the make
file. To do this pick from the menu Run -> External Tools -> External
Tools Configuration. Now right click on 'Program' and choose
'New'. Then set the following details:
- Name: make
- Location: /usr/bin/make
- Working directory: ${workspace_loc:/TestPlugin} (replace TestPlugin
with the name of your plugin directory)
Now click on the 'Run' button and the makefile will compile your UI and
RCC files. If you right click on the 'TestPlugin' project folder
and choose 'Refresh', you will see these resources appear in the
project. Any time you change the ui or rcc files you need to rerun the
make tool. More specifics on building user interfaces and resource files
can be found in the Qt and Qt-Designer documentation. If you are on a
windows platform, you probably won't be able to use the makefile (I'm
saying this without actually testing it), so you will probably need to
create individual helper tools.This article should give you some
hints.
Add a remote breakpoint
Ok so now we have all of the setup legwork out of the way, we can move
on to the fun part - running and testing our plugin. It is probably a
good idea to try to load your plugin in QGIS at this point and just test
that the stub created by the plugin builder works as expected. To add a
breakpoint we need to add PyDev to our python path. You can do this in
one of two way - updating your PYTHONPATH before launching QGIS so
that it can find PyDev, or appending PyDev to your python path at run
time. I chose the latter approach. Note that before you can start, you
need to understand where your PyDev python module is. On my system it
got put into:
/home/timlinux/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev.debug_2.2.4.2011110216/pysrc/
Your should be something similar - try running this command if you can't
find it easily:
locate pydevd.py
Now to add the breakpoint, we will first drop these few lines into the
top of our plugin (for example I put mine in
remotedebuggertestdialog.py):
import sys
sys.path.append("/home/timlinux/.eclipse/org.eclipse.platform_3.7.0_155965261/plugins/org.python.pydev.debug_2.2.4.2011110216/pysrc/")
from pydevd import *
And then anywhere in that file where you want a breakpoint to be
triggered, simply insert this line:
settrace()
Here is a screenshot of my plugin file ready for debugging:
Run the PyDev server
In order for Eclipse/PyDev to be aware of the breakpoint being reached,
you need to run a small server that will listen for a call from
settrace() and attach to that process. To do that, switch Eclipse to the
Debug perspective:
In the toolbar in this perspective, you will find an icon that will
launch the pydev server.
After clicking that icon, the server will run in the background and you
will be all set to start debugging.
Run the plugin in QGIS
Now run QGIS. It is important to note that you must start QGIS after
starting the PyDev debug server - otherwise the debug traces seem to
be ignored. The next thing to do is to launch your plugin in QGIS. As
mentioned before, you may want to set up the reloader plugin so that you
can reload your plugin in QGIS each time you make a change to it without
needing to exit and restart QGIS each time. You don't need to do
anything special otherwise, just click the default icon that was created
for your plugin.
Debugging in Eclipse
When the plugin launches, you should see Eclipse/PyDev kick in and halt
execution after the trace point. You can now use the normal Eclipse
debugging tools to step through the code, examine variables and so on.
If you make some changes to the code, just continue the running plugin
and close it, then reload the plugin using the plugin reloader, the
breakpoint should get hit and so on. I did find at times that the
breakpoint was ignored. This can be resolved by stopping and starting
the PyDev server and then restarting QGIS. Here is a screenshot of my
Eclipse session after the breakpoint was encountered:
In case it isn't obvious, you should remove the debugging stuff from
your production code!
Conclusion
One of the great assets of QGIS is the python language environment which
makes it very easy for even novices to develop new functionality in
QGIS. One of the difficulties with the python platform for me has always
been the lack of a nice way to provide a debugging environment for those
who prefer a GUI especially for new programmer users and trainees. This
article presents one way to address this and make it easy for new users
to get started with QGIS plugin development. If you are a windows user
and adapt these notes for your platform, it would be great if you could
make any notes about what you did in the comments below.