When it comes to rapid prototyping, Python is the go-to tool for me these days. It's fully equipped, very expressive and portable across desktop and even mobile platforms/iOS, so it represents a perfect fit for writing all kinds of small tools and applications, especially when productivity counts and raw performance does not matter that much.

Although writing the application back end in Python tends to be pretty straightforward, the real challenge arises when it comes to the UI front end. One can choose between various cross-platform toolkits like TkInter, Qt or wxPython, or use a direct binding to the native UI on the given platform.

For the best user experience, I prefer to use what is native to the target platform with a fallback to a cross-platform UI toolkit for maximum portability. This gives one great flexibility, however, maintaining multiple UI front ends introduces some verbosity, code duplication and mental overhead due to the different UI idioms imposed by the frameworks.

This made me think what would be the best way to help me reduce the amount of UI-specific code to a bare minimum in order to simplify the maintenance and also make the whole experience somewhat more pythonic. So eventually, I've come up with a simple declarative UI layout engine, which allows to define a tree of UI meta elements that then gets transformed into the final layout. The transformation is based on a couple of simple rules (captured in the internal nodes), which control the layout. This can be directly expressed in Python like this:

Besides that, there are no other links between the layout engine and the actual UI framework, which makes the whole thing highly decoupled and pretty compact.

The engine itself (in its current state) uses just two parameters 'min_size' and 'stretch' to control the layout. 'min_size' defines the minimum size under which the element cannot be collapsed, 'stretch' tells whether the element is fixed or flexible in size. So far these two parameters have enabled me to express quite complex layouts so I haven't needed to extend the engine any further, it's still just a proof of concept though, consisting of just a little above 100 lines of code, which is pretty encouraging I would say. Here it is: