In PyCon UK, the two keynote speakers, Mark Shuttleworth and Ted Leung raised the issue of how Python should "open up" and aim to be the best language at everything (Mark's point) and the easiest language to work with (Ted's point). I agree with both them, I was nodding all the time when they spoke. They focused on the web and on the desktop, respectively.

Here are my thoughts on the state of GUI toolkits and how could Python take a first step to be on the web.

GUI toolkits

They suck

I think it was Ted that pointed out that there are no good cross-platform GUI toolkits. He is a good authority on this matter, seeing that he was part of the Chandler project, that aimed to be cross platform from day one. I remember him saying:

There's something very wrong if the ugliest version of your product is the Mac version.

(Sorry if I misquote - just my memories!)

I couldn't agree more. There is no way right now to create state-of-the-art GUI application that runs on two platforms without writing the GUI twice. By "state-of-the-art" I mean, as Ted said, that this application should integrate so well in your desktop experience that given the choice to switch to a web application, you would deny!

This means that a user, when first launching your application, shouldn't notice anything. It should be seamless, look just right and more importantly, behave right. Of course it is the Mac users that complain about this so loudly, because the Mac platform gives you a wide variety of built-in behaviours that your application can use that when people roll their own, it looks weird. Look at the recent example of Firefox 3, that took great pains to look as a native application, and you still can't look up words in the dictionary!.

No wonder that people are turning to web applications. They can use them from both their home and their office, they look exactly the same and of course they have the added benefit of safekeeping all their data for them.

Cross-platform chimera

There are a couple of cross-platform GUI toolkits with Python bindings, such as PyQt4 and wxPython, but you could hardly call their API Pythonic or even simple. I've looked at tutorials and while at the beginning they look promising, at some point things get so hairy that I recoil in horror (in PyQT it was signals - why couldn't I use just a function?). In all fairness, I'm sure you can build good applications with them if you try hard, but it's not as easy as using the native API (.NET or Cocoa).

Now, I'm a Mac user for the past year, and of course I had to dabble with Cocoa, and I liked what I saw. An excellent visual designer, a dynamic language (even with an alien to me syntax), very elegant architecture (outlets and actions make for excellent encapsulation) and batteries included.

I was pleasantly surprised for the past 6 months about .NET, it has a sane API (although I don't like generated code), a rich set of libraries and of course the killer feature for me was that I didn't have to use C#, since IronPython has a seamless integration with it. I have a few peeves, but they are related more to Windows itself rather than .NET (can we get a standard way of displaying modal dialogs please?)

An idea

It seems like you have to be knowledgeable about your target platform to know how your application can integrate into it, so no framework can give you that. But the rest of the things you want to do, like buttons and windows and all sorts of widgets, are almost the same. I had an idea about how you could translate a GUI definition (in XML or Python) into multiple platforms. Interface Builder generates (as of Leopard) XML output, so you can start from there as a base and try to generate .NET code to build something similar. Unfortunately I had a look at the output of IB and it is a serialized object graph that looks too opaque to be of great use, but I still think that the idea could yield something. My feeling is that approach like this would have to be constrained and not aim to be the last toolkit you'll ever need. Perhaps the other way round (a translation of Python code to native widgets) would be interesting to try out as well.

Translation

The main point of the previous paragraph was to stop trying to reinvent the wheel and try to reuse tools and technologies that are already there. I'm not sure if the specific approach would work, but I think that there is an example of something like that that worked very well indeed.

Cappuccino/Cocoa

The crazy guys at 280North liked Cocoa and Objective-C too much. Their problem was that they were a web startup, not a Mac startup. So they did the obvious thing and implemented something that looks a lot like Cocoa and something that looks a lot like Objective-C on top of Javascript and named them Cappuccino and Objective-J. They have a finished product to showcase and I they made their libraries open source.

I think that these libraries will gain traction when people want to build web applications, but the point I want to make is that they didn't have to design another big API, they took something that was proven (Cocoa) and brought its ideas into the web. The fact that Objective-J can fool the untrained eye into believing it is Objective-C is irrelevant, although I think that even with a different syntax, if the underlying values were the same it would've been the same.

This is why I think that people could start doing the same thing with Python, with a very big drawback: There is no big and proven GUI Python toolkit that you can port to the web, and I think that there will be none unless some very big company invests money into creating one. (Mr Shuttleworth, time to put your money where your mouth is :)

It is a big undertaking, but not an impossible one. I'll stop rambling now...

September 19, 2008, 10:02 p.m. More (1047 words) 6 comments Feed
Previous entry: PySmell v0.5 released
Next entry: PySmell v0.6 released

Comments

1

Comment by Lucian , 4 years, 8 months ago :

You do have a point, but it's not really THAT bad.

While not ideal, I've found PyQt4 to be both pleasant and native enough on all significant (win, mac, x11) platforms. Signals are because of the c++ background, but they aren't that bothersome.

I never liked wx much.

SWT for python (not jython) does sound interesting, with that web backend of theirs. Maybe the D port of SWT could help with making a python binding.

2

Comment by Matt , 4 years, 8 months ago :

I've rather liked using wxPython. The later revisions have been more pythonic in their event binding, although I have to confess the layout algorithms still confuse me. I'm curious if you have more specific criticisms? I'm not saying there are none to be leveled -- specifically, wxWidgets as a whole seems to focus altogether too hard on things like 'art providers' and whatnot that are just modern-looking -- but it seems to me that it does provide a well-integrated toolkit, and it's supported by things like matplotlib and pyopengl. (And on OSX, there has been a marked improvement since 2.8.4, with better native look-n-feel.)

3

Comment by David Boddie , 4 years, 8 months ago :

You wrote: "I’ve looked at tutorials and while at the beginning they look promising, at some point things get so hairy that I recoil in horror (in PyQT it was signals - why couldn’t I use just a function?)."

I don't understand this point. Did you want to use a callback function for something? Can you elaborate?

4

Comment by Orestis Markou , 4 years, 8 months ago :

Well, in a PyQT tutorial I was reading, you were supposed to create event handlers by passing in functions as strings - I don't remember the exact details, but it went something like this:

bind(something, "self.clicked")

Not very good.

5

Comment by David Boddie , 4 years, 8 months ago :

You would usually connect signals from objects in the framework itself and slots (methods) implemented in Python with this kind of notation:

self.connect(obj, SIGNAL("signal(type1, type2, ...)"), self.do_something)

So, to be notified each time a button is clicked, you would perform a connection like this:

self.connect(button, SIGNAL("clicked()"), self.do_something)

It's not all that great that the signals are specified using strings, but there's no reason to do the same for slots. In prinicple, there's no reason why signals couldn't be defined as objects and assigned to the objects that emit them. That way, you wouldn't have to worry about mistyping signal signatures.

Incidentally, events and signals are used for different things in PyQt. Events are typically used for things like repaints, key presses and precise mouse clicks whereas signals tell you if a button was clicked, a menu item selected, and things like that.

I co-wrote a presentation that briefly covered the basics of PyQt. You might find it interesting:

http://indico.cern.ch/contributionDis...

6

Comment by luke kenneth casson leighton , 4 years, 7 months ago :

Pyjamas (http://pyjs.org) and Pyjamas-Desktop (http://pyjd.org) are a pair of python technologies that allow you to develop applications that will run - unmodified - in both a web browser and on the desktop.

Pyjamas has a strange history. It's a port of Google's Web Toolkit (GWT) from java to python. So, whilst GWT is a Java-to-Javascript compiler and associated Widget Set, framework, and AJAX library, Pyjamas is a python-to-javascript compiler, with the same GWT Widget set ported to python, pretty much the same framework and pretty much the same AJAX library.

Then, because the Pyjamas Widget set looks so startlingly similar to a Desktop Widget set, Pyjamas-Desktop /makes/ it a Desktop Widget set, by ripping out all of the javascript and replacing it with identical python code.

How this was even possible was thanks to Webkit (http://webkit.org), which has had glib / gobject bindings added to the DOM model. So, in a similar fashion to how PyDOM / PyXPCOMExt works, and how the Python bindings to KHTMLPart in KDE work, you can manipulate the DOM model of web technology.

The level of manipulation, control and flexibility is sufficiently powerful to the extent that, with the right libraries, it actually looks far better than anything that wxWidgets, PyGTK2 or even PyQt4 could come up with.

With the added bonus that the same application - identical to the "original" can be compiled into javascript, and run in any modern web browser!

It's just... so bewildering, it's going to take a while for people to realise that all the sheer hard work in making two wildly different applications is just... no longer necessary.

Now what would be really nice would be for GWT to do the same thing - get a GWT-Desktop port.


This post is older than 30 days and comments have been turned off.