A Python Ate My GUI
Thoughts on the future of Python and graphical interfaces
Staring at my coworkers, already knowing the inevitability of the situation, my eyes roll as the argument starts anew:
“I told you I can write that code twice as fast, in half as many lines and they’ll be cleaner and more readable than yours will ever be! Python is awesome!” — said the one guy.
“Whatever you say, you’ll never be able to make a UI that’s half as good as this. It won’t look pretty and no one will want to use it!” — replied the other — “Probably can’t even make it run on Windows” — he mumbled to himself while walking away.
Some years ago this was a regular exchange between coworkers, and while they were mostly messing around, there was still an element of truth to it. Regardless of its capabilities, Python was mostly known as a “scripting” language — not really for graphical interfaces — and the world was still looking for a native OS feel in their GUI applications, which was not really accessible from Python without a lot of work.
Where are we now?
Fast forward a number of years and we have quite a few widget libraries available out there beyond tkinter or wxwidgets, the most notable ones being *PyQt *and Kivy. We also have good end-user applications that provide rich GUIs, like for example the Dropbox desktop app.
However, while all of these modules have implemented widgets in their own unique ways, I contend that we still have not definitively solved GUI in Python, especially when designing for cross-platform or when thinking about mobile.
PyQT and the licensing gremlins
As one of the most used and feature rich modules, it’s entirely possible to produce decent GUIs with relative ease. The QT library itself is also available on other languages like C++, so it’s already familiar to some programmers. It’s capable of generating native-looking widgets by drawingthem like images, and in some cases may provide a speed advantage over native.
However, there’s this: QT License FAQ
I’m sorry, but if you need an FAQ section for people to understand how they can legally license your product and still be able to have control over their work, then you’re still living in the 90s. This is really not a problem that I want to be worrying about, no matter how good your library is. Plus the nature of Python itself, presents some interesting complications when considering distribution in these situations.
Given the openness of the community and the popularity of MIT licensed code, I just don’t consider this viable anymore.
What about Kivy?
Kivy is a very clever solution that becomes OS agnostic through the use of OpenGL interfaces to directly draw their widgets.
These guys have put in an great effort and done a good job. They developed their own description language to help structure complex environments, done the work to have it function on mobile platforms, integrated new user input paradigms (like gestures) and have no licensing issues.
What’s the drawback? It’s great for games and smaller applications, but I find it harder to use for business apps that need to represent a lot of data, like complex tables.
What now?
Smartphones and the mobile world have deeply affected the UI landscape for every platform. People want sleek and intuitive interfaces that evoke creativity, like what they’ve come to expect from Apple products, and to some extent Android. They don’t necessarily evaluate your application by its use of native widgets, in fact they now want things to look like what the web provides with CSS and HTML5.
Popular libraries and templating systems have evolved considerably over the years, effectively democratizing common metaphors for user interaction. Just look at Bootstrap and Foundation, or even Ionic and WordPress. These systems make it fairly easy to put together a good-looking website fairly quickly.
The web browsers themselves, as well as the JavaScript language, have also advanced to the point of providing speed and compatibility at a level that never existed before. Which in turn has led to single-page web applications that reconfigure themselves as if using native widgets instead of loading into separate individual webpages.
To top it all off, HTML5 and its SVG tag have ushered in advanced vector graphics support. Have you seen what d3js can do? Then there’s WebGL, another technology that now a number of game engines are targeting, allowing developers to produce performant 3D games within your browser.
Given all these advances, I find myself writing a bunch of JavaScript or HTML code in order to provide a front-end to my Python, and as much as I may like making pretty things, readability and maintainability suffer greatly with those languages.
At the same time, I seem to be repeating the same patterns in creating those interfaces, connecting them to my backend code and wiring up the eventing I need to have a functional web application. And of course, switching between languages and coding practices can really muck with your style (or prevent you from having a good one in the first place). So I ask:
Why not design a Python package for interacting with users based on all these technologies put together?
Would it be possible? I’m not talking about another web server like Django or Pyramid, in fact I think the very idea of Django and similar frameworks should go away. I find templates cumbersome, hard to read and non-pythonic.
I want to write Python code that spits out the HTML and JavaScript required for these interfaces and I still want to handle all the logic in Python. I don’t want to touch any other layers unless I need some specific tweaks to the widgets. I want to automatically use whatever relevant JS libraries I need like D3, DataTables, jQuery, etc. all from my Python code. I want it extensible such that new “widgets” are easily built on top of the base platform, and using them would be as simple as importing a module. I want it all with cross-browser support, and I want to be able to deliver it as a self-contained application.
What am I going to do about it?
Since there are a lot of “I wants” in that last paragraph, I decided to take a stab at how I would do it. Have a look at the next part in this series covering some of the design steps of my solution.
If you have any suggestions or ideas on what you’d like to see or how you’d want to see it implemented, leave it in the comments.