PyGUI as a standard GUI API for Python?

Orestis Markou 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
http://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
> ways.
>
> to explain: pyjamas is a widget set api that looks desktop-like; you
> write code in python, it's compiled to javascript; the DOM.py module
> 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  
> down-
> side: it didn't have python bindings.  a quick search showed
> pywebkitgtk.
>
> so, i decided to try something absolutely awful: wrap the
> _javascript_!  i augmented pywebkitgtk, thanks to some assistance from
> the author of midori i borrowed some of his code and made it possible
> for pywebkitgtk to execute javascript code-fragments (equivalent of
> 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,  
> c+
> +, 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
> being able to execute javascript fragments, if you're feeling
> 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
> to do it as javascript fragments).
>
> 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
> horizontal-first.
>
> 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
> limitations.
>
> 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
> clumsy.
>
> 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
> _real_ web browser, by being compiled to javascript.
>
> 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
> (pywebkitgtk).
>
> 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
>
> l.
> --
> http://mail.python.org/mailman/listinfo/python-list




More information about the Python-list mailing list