Comparison Of Python Toolkits: PyQT, PyGTK/PyGNOME and wxPython

Filed under: myddrin @ 10:02 am

During the last few weeks, I have been trying to decide the future of the
Cathbad project. The project was always designed to support multiple
toolkits and languages, but the question of “which toolkit next” is
important for licensing reasons. Currently, the application is
based on PyQT which is released under the GPL for Mac and
X11(Unix, *BSD, etc, etc), but not for windows. This puts a
serious limit on the developers who can participate in the project,
and its parent project GnosisLIMS. (This limit will be removed
with QT 4.0, but at the time that seemed months away.)

In late December, 2004 I decided that the next toolkit to be implemented
would be wxPython. The toolkit is popular, well supported and
well funded. (OSAF has been funding developers since wxPython
is at the core of their Chandler project.) Work on this started in
March of this year and was quickly bogged down. It was not (I have
concluded) the fault of the toolkit, but rather the drudgery of
reimplementing the same code with only minor changes.

During the same period, I was working on a tool to help me manage my
email. Specifically, a tool that would allow me to be notified of
important emails when I was away from the desk and send autoresponses
to specific people. The core concepts of this project ( flex-mn) were
multiple actions per email address, and I wanted the ability to extend
the program easily so that if new technologies became availible, I
could easily take advantage of them.

Initially for that project, I selected PyGTK primarily because I wanted
the program to be a GNOME applet which I could embed in a panel. This would
allow me to check the email counts while I was walking past the computer.

Development for that project took roughly a week, and at the end
of that time I released it on freshmeat.net. The response was pleasing,
and the projected ended up becoming a centerpiece in interviews. There
was a great deal of interest from Windows folks and Mac folks, so I decided
to see if there was a way I could make some version of the project availible
to them. I quickly found that wxPython suited the bill well. It was
portable to Mac and Win32, and would also allow KDE users to use the
project as well.

Combine that with 2 years working with PyQT at a previous position and I
find myself with experience in three major UI toolkits for the python
language. So, I thought I would pass my impression on to everyone.

PyQT

PyQT is based on the sip library for python bindings, and is written/supported
by Riverbank Computing. This sip library is used to create python bindings
for TrollTech’s QT toolkit. The library is at the core of theKompany’s
BlackAdder product, and allows for cross-platform development. QT wraps
the OS native APIs for network access, database, user interface controls,
and just about anything else you can imagine.

Pros:

PyQT is amazingly simple to pick up and learn. The documentation is
exceptional either by going to TrollTech’s website and converting the
examples to python, or by purchasing python docs from theKompany.

User Interfaces in PyQT look sharp and integrate virtually seemlessly
into the native desktop. (I have heard some complaints from Mac users.)

The most common (see below) eventing mechanism is based on signals
and slots. This is an advanced callback system that allows multiple method
calls to be associated with a single event(signal). Once you have this
capability, it ends up being hard to go back to having a single callback.

Cons:

As I see it, there are three big concerns I have when starting PyQT
development. Two of these will be dealt with the upcoming 4.0 release.

1) Licenesing: Open source development on the Windows platform is not
currently possibly unless each developer has a QT and PyQT license
AND a special exception is made for the QT toolkit’s license. This can be
akward for open source development, but with the 4.0 release this issue
will be resolved. For closed source development, licenses are available
at a reasonable cost.

2) The Eventing Mechanism: Currently, QT does not allow signals to pass
between threads. If you need to signal another thread, you must use a less
flexible eventing mechanism using QEvents. This is annoying because you
have to switch back and forth between two very different approaches to
eventing. This issue will be resolved with the QT 4.0 release.

3) Threading: PyQT introduces QT threads to the python environment. As
best as I can tell, these are true threads, unlike the python-native
psuedo-threads. While this is a welecome addition to the python language,
it can create issues if you are embedding python or try to mix python and
QT threads. If the threads on are not carefully isokated (communicating
through python Queue objects), your program may become erratic,
crashing at unusual times.

PyGTK/PyGNOME

As stated above, I initially selected PyGTK because I wanted an applet.
Since I use GNOME primarily (at least on my main desktop), the library
was a natural choice. Additionally, PyKDE (the library that would
allow me to create a KDE applet) is based on PyQT, which I already
know pretty well..

PyGTK is a wrapper for the GTK cross-platform toolkit. This toolkit
was originally designed as part of the GIMP project, and as grown
from there. I am unsure of how the crossplatform nature is acheived,
however I have noticed that GTK applications running on Win32 have
some non-windows behaivors (mostly to do with the clipboard).

Pros:

PyGTK allows for seemless integration into the GNOME desktop, and for
programs to be launched in KDE (although they don’t “feel” right in
that context.

The development is pretty straight forward, with a simplistic
event/callback mechanism. (see below)

The listbox and combobox controls are exceptionally powerful. They are
based on the Content Model View. This allows for very complex data to be
represented. (See below, however).

License: PyGTK is licensed under the LGPL. This allows it to be used in
closed source projects, on the condition that changes to PyGTK be released
under the LGPL.

Cons:

1) As mentioned, when run on platforms other than GNOME, there may be
some oddities in behavior. For many simple applications, this may be
fine. Also note, that this is my experience as a user. This may the
result of developer choices in the applications themselves and not an
issue with the toolkit itself.

2) I found the documentation lacking in several places. Instead of going
to the PyGTK website or the GTK website, I found myself using Google
to find example code. This was not a major issue, but should be mentioned.

3) While the CMV model for combo boxes and list boxes is great, it can be
frustrating, especially if you are clearing/re-adding data on a regular
basis (like I was). The library provides a function for creating “Text only”
combo-boxes, but once the model is cleared, new data can not be re-added.
A subclass that provides a simple text-only combo box that can be cleared
and re-populated would be most helpful.

4) The Eventing Mechanism: For my project, I needed to create custom
events for signaling when a dialog box was complete, and so forth. I was
not able to locate how to create custom events, but I could find an older
article that said that it was not supported. So I had to find a work around
for this. (This may be my lack of knowledge here, however
if this is true, it’s a fairly big deal as eventing appears to be
the only signalling mechanism in the library.)

wxPython

As stated above, wxPython was selected so that I could provide task bar
icons for Win32, Mac and KDE users. The library is still under heavy
development, and this can occasionally show. However, it is also easy to
see why it is becoming

The library acts as a wrapper for other libraries, on windows it wraps
Win32, on Mac it wraps calls to Aqua (or whatever the Mac UI library is
called) and on Linux/Unix/*BSD it wraps GTK. This last one I found a
little surprising since GTK is built on even lower-level libraries. The result
is that wxPython is a binding for a wrapper that wraps a wrapper.
However, while my first thought was that this would be slow, it it does not
appear to be so.

Pros:

Simple straight-forward eventing mechanism.

This was the only cross-platform library I could find that supported task
bar icons on all platforms. While this may not seem like that big
of a deal, for some projects this makes it the only choice.

The license is a modified LGPL that allows closed source projects to
keep their modifications to the library closed.

Applications blend in well with other applications on the platform.

Cons:

The library is still a little rough around the edges. I encounted this
when I was attempting to create buttons for my UI. The system kept
segfaulting until I found the “right way” to instantiate them. Searching
the web, I found several instances of this. The reponse seemed to be
“we are working on it, until then try to find a combination that works.”
This was frustrating.

Some of the class names seem odd(wxStaticText instead of say, wxLabel),
which makes learning a little more painful. However, once you
get accustomed to it, the names have their own internal logic.

Conclusions

The choice of a UI toolkit is largely one of preference. A developer
experienced with a toolkit can find work arounds for even the most
outrageous bugs or design flaws. However, when picking a toolkit
it is always important to think of the people who will be
maintaining the code after you. Will the next developer have
to be an expert in the toolkit (in order to understand all
your workarounds) or will they be able to pick up the toolkit
basics and “just go.”

I think that it is that aspect of a toolkit that really speaks to its
quality. It encorporates the number of bugs, the design and the overall
nature of the toolkit.

And when it comes down to it, these three toolkits are all very high
quality. I know that I ragged on this one for some flaw or
that one for some flaw but overall these are highly useable,
flexible toolkits. When compared to the wall of obsufcation
that is the win32 api or MFC, it becomes apparent that these
toolkits have many advantages. They are designed well, they behave
(mostly) as documented and there are very few “magic calls” required
to make things work. (These are calls that are usually undocumented
but without them the toolkit behaves erratically.)

At this point, the reader is probably saying “yes, but what
is the ‘best’”? Well, that is difficult to pin down. In many
ways these toolkits use the same overal design (with different
names). Also, they all have issues unique to their implementation.
I think the best analogy is to look at selecting a hammer. You
wouldn’t use a sledgehammer on nails, nor would you use an
every day hammer to knock down a wall. The toolkit you select
is going to be highly dependant on what you are trying to do.

If you are primarily a windows developer in a closed source shop
that wants to stay that way, then PyQT is probably
your best bet. It is easy to pickup, there are tools available for
MFC conversion or integration and it has a greate ActiveQT framework
available to enterprise users that allows you to quickly (and I mean
QUICKLY develop ActiveX controls. It is also cross platform,
so you can easily move your work to Mac or Linux/Unix/*BSD.

If you are a windows developer who know they will be switching to
Linux/Mac/etc soon, then your options increase.

If your company is willing to dabble with open source, then PyGTK is an
option. You will be able to keep your main product closed, while
releasing any fixes to the PyGTK toolkit under the LGPL. Although, for
the most part if you are looking at supporting Mac and Linux, you will
likely want to use wxPython.

If your company wants to remain completely closed source, then
you will likely want to look at wxPython or QT. The QT track
will cost more money (as you will need to purchase closed source
licenses), while the wxPython is no-cost.

Additionally, when you want to simply support Linux/Unix/*BSD, it
largely depends on the requirements of the project. If you want to integrate
tightly with the desktop, then you will want PyGTK or PyQT’s cousin
PyKDE.

If you will be targeting the KDE desktop, then PyQT is probably your
best bet (Although, keep in mind you will need closed-source licenses to
both QT and PyQT). If you are targeting the GNOME desktop, then
wxPython or PyGTK makes sense. And if you are generically
targeting “Linux”, then I would give the nod to wxPython, largely
in terms of cost. (If you are an open source developer, this
is much less important.)

Support is also an important issue, To date, I’ve only hade to get
support from TrollTech, and in that case they responded very quickly
and were quite helpful. the other hand, they were being paid for a
support contract. For the most part, however I’ve found that
community based support is more than adequate in the vast majority
of situations.

So overall, if you are looking to do cross-platform python UI development,
you have several choices. The libraries are all high quality, and perform
well on differing platforms. In the end, the toolkit you select will
largely be a matter of personal taste and the requirements of the project
itself, but I think this article as laid out some of the highpoints and
pitfalls of each library.