PyGUI as a standard GUI API for Python?
orestis at orestis.gr
Mon Oct 13 23:59:56 CEST 2008
Just want to say, thank you for a very enlightening writeup. You
should really post this somewhere that we can link to.
orestis at orestis.gr
On 11 Oct 2008, at 10:19, lkcl wrote:
> On Sep 3, 4:34 pm, Michael Palmer <m_palme... at yahoo.ca> wrote:
>> So far, development of PyGUI seems to be a one-man effort, and it may
>> be slowed down by the attempt to develop the API and the
>> implementations concurrently. Could it be useful to uncouple the two,
>> such that the API would be specified ahead of the implementation?
> michael, i went back to the beginning of this thread, to reply to your
> question, because i have some insights to share with you from my
> failed attempts on porting pyjamas to the desktop - which you can
> collect here: http://lkcl.net/pyjamas-desktop
> there, you will find an IronPython-GtkSharp port; a pyqt4 port and a
> pygtk2 port. they were each failures in their own unique and special
> to explain: pyjamas is a widget set api that looks desktop-like; you
> actually does things like document.getElementById() etc. etc. and in
> this way you end up completely manipulating the DOM model, turning the
> browser into just a giant desktop-like canvas.
> in fact, the pyjamas widget set api is _so_ similar to a desktop api
> that i decided to have a go at porting it _to_ the desktop.
> eventually i succeeded.
> the first attempt was with ironpython. i actually got a long way with
> this one - i chewed through the pyjamas examples in about a day. i
> had a small stumbling block implementing the HTML() widget, but
> GtkSharp.HTML came to the rescue, there, and i was off again.
> i then ran into a wall i decided not to bash my head against at such
> an early stage (36 hours) - an implementation of XMLHTTPRequest
> (remember - i was implementing every single bit of functionality that
> a DOM model has access to).
> so, i decided to port the ironpython port to pygtk2. unfortunately,
> whilst i got a lot further and managed to implement all of the
> examples, there was no equivalent of HTML(). GTK itself totally lacks
> a rich media content widget. there is python-gtkhtml2 which is good,
> but not good enough. the much better gtkhtml3 library doesn't have
> python bindings around it, and i wasn't in the mood to write any (and
> hadn't at the time any experience with pygtk codegen.py).
> also i heard that gtkhtml2 had been abandoned, and gtkhtml3 wasn't
> going to be followed up on, and that there were rumours about webkit.
> crucially - much more importantly - gtkhtml 2 and 3 have absolutely no
> "automatic" resizing of the HTML content within them. so, unless you
> specify both the width and the height of the widget container, you end
> up with a flatlined widget. by that i mean a widget of say 200 pixels
> in width but ZERO pixels in height! and, as you may well know, if you
> specify a width and height on a gtk widget, that's it: it's entirely
> fixed. there's no going back. you're screwed.
> this was an absolute killer.
> with no foresight in the design of gtk or gtkhtml2 to make even a
> _guess_ at the width and height of the content, the port was screwed.
> i made half-hearted attempts to not specify width/height at all, but
> all that that resulted in was piss-poor layout, and when you shrank
> the app to small size, all the text disappeared because there was a
> margin defaulting to 5px or so and all but the top left corner of the
> text boxes would disappear!
> so, there was no point in me attempting to make python bindings around
> gtkhtml3, even though it has a system for inserting widgets into HTML
> (using span ids).
> and, even though there's python-gtkmozembed wrappers which would have
> allowed me to embed flash plugins etc. into my application, thus
> neatly emulating the way that html allows you to do that.
> so - sadly - on to pyqt4.
> well, i say sadly, but it was actually quite fun. i'm doing a
> complete comprehensive test of absolutely every single feature of the
> major widget sets out there, crawling every single corner of their
> functionality in order to map concepts one-for-one, and finding that
> they don't really cope.
> pyqt4. again, i got a long long way. the rich media support of qt4
> allowed me to do widgets that looked reasonable. i even had, by that
> time, a non-asynchronous version of XMLHTTPRequest. then i got to the
> implementation of Grid() and FlexTable(). this is where it started to
> go wrong.
> pyqt4 has the concept of layouts. a layout can be a horizontal
> layout, vertical, grid, and you can even specify the percentage or
> ratio of the width (or height) that individual cells can use. you
> attach a layout to a widget; you can attach layouts to layouts. you
> can remove layouts from widgets. what you _can't_ do is _remove_
> layouts from layouts.
> disappointingly, this was the killer, for me. it was just getting...
> too complicated. i had already encountered advice that, in order to
> implement the means to move widgets around, i should remove
> *everything* and redo the layout. it just... wasn't happening.
> plus, i think also that there are problems, again, with the HTML
> layout: you can't _entirely_ stop text-squashing. so, although pyqt4
> was _better_, it still wasn't _enough_.
> so, i was _almost_ ready to give up, entirely, when i'd heard about
> webkit - http://webkit.org - and this looked _perfect_. the only
> side: it didn't have python bindings. a quick search showed
> so, i decided to try something absolutely awful: wrap the
> the author of midori i borrowed some of his code and made it possible
> eval and exec). except, immediately i ran into a problem: how to pass
> in function call arguments. i decided against doing func_code
> grunginess and creation of variable scope management to emulate python
> local function call context (!!!) and instead... insanely...
> ... dived straight into adding glib bindings around webkit, with a
> view to then doing python-bindings around the glib bindings, using
> pygtk2's "codegen.py". ... cue piped elevator music and such-like, to
> substitute for two weeks of intensive programming, involving python,
> +, perl, c ... suffice to say: it worked. it actually bloody worked.
> very very quickly, i was able, once i had the glib bindings, to port
> pyjamas to webkit. i had my first succesful hello world within under
> an hour; i had most of the examples done within 18 hours or
> thereabouts; the entire port was completed within about five days,
> because i had to go back and add extra functionality such as event
> handling and XMLHTTPRequest.
> when i say "done" i mean that you can do eeevvverrryything that
> everyone keeps lamenting about that pygtk2 and pyqt4 lack. complete
> and full support for CSS stylesheets. complete and full support for
> embedded plugins (such as adobe). complete and full support for HTML
> syntax. _proper_ HTML, not a subset. you even get the added bonus of
> particularly obtuse.
> and, with a few days extra work on the glib bindings, you'd even be
> able to run SVG canvas from python (whereas at the moment, you'd have
> the moral of the story is that web browser technology makes for a hell
> of a lot better widget set than a desktop-designed widget set does. a
> _lot_ better. there's been far more effort put into it, for a start.
> browsers are designed to make the content look "readable" in far more
> circumstances - hostile and conflicting circumstances - than desktop
> apps are. we stare at browsers far more than we do at desktop apps,
> for the most part.
> and so, you get things like text flowing neatly around, and even
> widgets flowing neatly. _properly_. you can even specify, thanks to
> CSS styling, whether you want the "flowing" to be vertical-first or
> imagine trying to implement that with GTK2 or QT4 - it'd be a
> _nightmare_ gone wrong. yet, browsers have been doing text-flowing
> and div-flowing for... forever.
> now, at this point, having got what i wanted, i didn't want to spend
> time on wxWidgets, but i can imagine that there would be similar
> the issue with implementing a widget set is that there is a very
> specific set of functionality that is absolutely absolutely required,
> and without every single bit of functionality, you are entirely
> wasting your time to make the port. threading. timers. rich text
> (aka HTML). event handling including window resize, onload, mouse
> over, in, out, move; keyboard handling; asynchronous external
> communication with the rest of the world. embedded plugins. layout
> management, including horizontal, vertical, grid and flow, with
> _decent_ cell proportion subdivision of available space, and respect
> for minimum widths / heights as well as fixed widths / heights.
> without _all_ of these things, done properly, you're hosed before you
> even begin to create your widget set "wrapper".
> GTK lacks flow-layout, rich text support and proportion subdivision of
> layouts, making every GTK application in existence look utterly...
> shit. scuse my french. fortunately, someone's come to the rescue
> with a gtk theme engine which allows you to customise gtk with CSS
> stylesheets, but it is early days yet.
> _other_ than these significant failings, GTK is technically pretty
> damn good and provides everything else you'd need - including
> embedding flash and other plugins by leveraging mozplugger - in an
> easy-to-use and well-documented fashion.
> QT4 lacks crucial layout management (layouts not being deletable from
> layouts), flow-layout, and variable-sized rich text. they _do_ have
> proportional subdivision of layouts (allowing you to specify a fixed
> width on one cell and a percentage width on others) but it is very
> other than those failings, which are less than those of GTK2 but as
> equally significant, QT4 _looks_ better than GTK2 but ... it's still
> not good _enough_.
> when you've written an app with pyjamas-desktop, and it looks good no
> matter whether you resize the window to 1200x800 or down to 320x800,
> because you cater for onResize events and reformat the layout, _then_
> you know you're on to a winner [my first ever pyjamas app was my own
> web site - http://lkcl.net/site_code - see the onWindowResize
> function, which adapts the site layout. _yes_ my web site runs under
> pyjd as a desktop app :) ]
> and - this is the kicker: the pyjamas API itself, as long as you stick
> to it, you know that the same application will run - unmodified - in a
> now all i have to do is investigate pydom and pyxpcomext, because -
> again, porting pyjamas to utilise pydom i believe will be utterly
> trivial. if i hadn't had to cater for some of glib's foibles, with
> silly naming conventions, i reckon i'd be done in about 16 hours flat
> (i'll let you know how i get on, when i have 16 hours of time
> available to _try_!).
> oh - one last thing. glib != gtk. therefore, the possibility exists
> to do a pywebkitqt4, a pywebkit/wxWidgets, and, also, thanks to google
> chrome's use of webkit, what google have done is write their OWN
> drawing library (!!!) making ANOTHER graphics-port of webkit that is
> completely independent of and having nothing to do with gtk2, qt4 or
> wxWidgets. then what they have done is provide accelerated drivers
> for ARM-embedded devices (in android) and another one for windows.
> ripping that library (i forget its name) out of the clutches of the
> monster 450mb hairy tarball that is called "google chrome" should be
> given some high priority.
> anyway - the reason i mention it is because with a tiny bit of messing
> about, you can get a pywebkit-<anything> that is entirely and wholly
> independent of the underlying "helper-widget-set" on which it sits.
> the only real reason why, then, you would want to use a particular
> pywebkit-<xxx> - e.g. pywebkit-qt4 with bindings to the DOM model -
> would be because you wanted to embed the webkit engine into an
> existing pyqt4 application.
> in this way, i hope that i have highlighted that the pyjamas API is
> entirely independent of the "underlying" widget set which it uses to
> draw on-screen, making it a proper "cross-widget-set" API, even though
> at the moment there is only widget set that it's been ported to
> the summary: doing a decent cross-widget-set API that is also cross-
> platform, cross-desktop, cross-browser is damn hard - but it _can_ be
> done, and _has_ been done, albeit in a very roundabout and obscure
> fashion. http://pyjs.org and http://pyjd.org
More information about the Python-list