PyGUI as a standard GUI API for Python?

L

lkcl

Here is the tutorial I've started in order to show off building a
Python/XULRunner GUI application.http://pyxpcomext.mozdev.org/no_wrap/tutorials/pyxulrunner/python_xul...

The details in this tutorial mostly targets a Windows/Linux platform
(MacOSX is possible with a few deviations, I have tried to cover these
deviations where applicable).

Feedback is welcome.


oh for _goodness_ sake :) i don't know whether to be derangedly-happy
and overexcited that pyxpcom and pydom exist, or whether to be annoyed
that i'll have to do _yet another_ port of the pyjamas widget set api
to another platform.

how come this stuff is so hard to find? it's a _brilliant_ idea to be
running python in a web browser, direct.

l.
 
L

lkcl

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.
 
D

David Boddie

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.

You can remove layouts from layouts with the QLayout.removeItem() method.
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.

You'll need to delete the contents of those layouts yourself - maybe that's
the real problem. You shouldn't need to redo the whole layout structure,
though.
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_.

These days, you'd probably use PyQt4's WebKit integration for HTML
rendering, anyway, though I imagine that it doesn't help you much if
you're already using WebKit directly.

[...]
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.

You can write your own layouts as well, but maybe that's more work than
you're prepared to do, especially now that you seem to have settled on
WebKit as your toolkit.

David
 
L

lkcl

You can remove layouts from layouts with the QLayout.removeItem() method.

yes... it didn't work. a layout within a layout - i think it was a
QHorizontalLayout within a QGridLayout - didn't want to be removed.
it's probably a bug.
These days, you'd probably use PyQt4's WebKit integration for HTML
rendering, anyway, though I imagine that it doesn't help you much if
you're already using WebKit directly.

[see below...]
You can write your own layouts as well, but maybe that's more work than
you're prepared to do,

definitely.
especially now that you seem to have settled on
WebKit as your toolkit.

well, it just made vast amounts of sense - cut out all the middle
men. if you're going to pull in a 17mb binary dependency, why do it
in a clumsy way?

in order to pull in flash plugins and other material, the accepted
method in pygtk2 is to use python-gtk-mozplugger. that's crazy.
embed an _entire_ web browser, just to pull in a flash component.
likewise, for doing a single bit of HTML, in pyqt4 and/or pygtk2, pull
in a 17mb binary dependency using python-webkit-qt4 and/or
pywebkitgtk, _just_ to display _one_ bit of HTML text?? _that's_
crazy.

especially as webkit actually has far better rendering capability,
features and flexibility than any of the standard desktop widget sets
which had been designed for the job!

wonderfully ironic...

oh - for completeness, if anyone's reading this and goes "no chance i
will _ever_ convert to the pyjamas API because i've spent so much time
writing pygtk2 apps" - there is a project by luis pamirez, where he
has _reimplemented_ gtk.py, gobject.py and gdk.py to sit _on top_ of
the pyjamas DOM model.

at present, it's only available in the subversion repository of
http://code.google.com, and you'll need to check out a revision some
time around sep 2007 of the llpamies branch.

basically, what that will give you is a means to run your pygtk2
applications... in a web browser!

very cool. i'll do a port to pyjamas-desktop at some time, if i have
a need for it, and will be happy to help guide anyone who wants to
spend the time on it themselves.
especially now that you seem to have settled on WebKit as your toolkit.

well, it's not _my_ toolkit - i just use it. but you're right
inasmuch as i won't be initiating any new applications using pyqt4 or
pygtk2, not out of personal choice, anyway.

l.
 
D

David Boddie

yes... it didn't work. a layout within a layout - i think it was a
QHorizontalLayout within a QGridLayout - didn't want to be removed.
it's probably a bug.

Was it detached from the layout, but still visible?

[...]
in order to pull in flash plugins and other material, the accepted
method in pygtk2 is to use python-gtk-mozplugger. that's crazy.
embed an _entire_ web browser, just to pull in a flash component.
likewise, for doing a single bit of HTML, in pyqt4 and/or pygtk2, pull
in a 17mb binary dependency using python-webkit-qt4 and/or
pywebkitgtk, _just_ to display _one_ bit of HTML text?? _that's_
crazy.

Sure, if all you want to do is display one bit of HTML text. It always
helps if you choose the most appropriate libraries for each task.

David
 
T

Terry Reedy

lkcl wrote:

I got the impression that there is currently no Windows binary
available. Correct? If not, perhaps someone trustworthy will someday
donate one.
 
L

lkcl

You can remove layouts from layouts with the QLayout.removeItem() method.
Was it detached from the layout, but still visible?

i don't know if it _was_ detached from the layout, but it was
definitely still visible. see http://pyjs.org/examples/gridtest/output/GridTest.html
for the example i was porting to pyqt4. each time i clicked "Next", a
new set of N,N would be _overlaid_ on top of the old ones, even though
i was doing removeItem().

the code's at http://lkcl.net/pyjamas-desktop/pyqt4.tgz

although i'm interested to know if there's a solution (to this
particular problem), the amount of additional work to provide an
equivalent of the "1px", "10em", "25%" etc. subdivisions on layouts,
and the amount of additional work to provide "flowing" and HTML-
substitutable layouts (see http://pyjd.org/api/pyjamas.ui.HTMLPanel-class.html)
is just... it's a lot of work.

l.
 
L

lkcl

lkcl wrote:

I got the impression that there is currently no Windows binary
available. Correct? If not, perhaps someone trustworthy will someday
donate one.

sorry, terry, you deleted a bit too much context :)
so, assuming that you mean "that there is currently no http://pyjd.org
windows binary", then then answer is:

pyjamas-desktop is pure python, relying on a modified version of
pywebkitgtk and a modified version of webkit to add glib bindings to
it.

i spent one week fighting with mingw32 to cross-compile webkit for
win32 - when i say fighting i mean segfaults at link time (!!), which
was tracked down to the msvc-compiled version of libicu 3.8 and
eliminated by hack-compiling libicu with mingw32; _rebuilding_ mingw32
from the latest svn at the time, in order to include support for
exceptions across thread boundaries (libstdc++ exceptions -
libgcc_a.dll)

all in all, it was a bitch :)

_then_ i started on cross-compiling python2.5 because there's no .exe
or .zip installer for python - only a .MSI, and, having installed MSI
under wine on linux with the excellent "winetricks" script, it causes
a segfault when you try to run a .MSI.

cross-compilation of python2.4 was successful (by the person who did
the initial patch, a year ago). cross-compilation of python2.5, to
generate a libpython2.4.dll and .a, fails miserably.

why the python developers didn't include the patches, and keep them up-
to-date, isn't clear.

at that point, i gave up, despite valiant efforts, because it was
clear that, given that there was no financial incentive to continue, i
was wasting my time.

the bottom line is: if you want a windows version of pywebkitgtk, i'm
happy to assist and advise anyone of the process- it should be quite
straightforward _if_ you have MSVC and follow the standard procedure,
but i'm not about to spend my own time and effort on providing a win32
port using ming32, doing all the work _myself_, on my own, without
financial incentive and renumeration.

i'll happily explain to other people what _they_ need to do, though.

l.
 
P

Propad

the bottom line is: if you want a windows version of pywebkitgtk, i'm
happy to assist and advise anyone of the process- it should be quite
straightforward _if_ you have MSVC and follow the standard procedure,
but i'm not about to spend my own time and effort on providing a win32
port using ming32, doing all the work _myself_, on my own, without
financial incentive and renumeration.

Is Visual Studio 2005 OK, or is some other compiler required?
i'll happily explain to other people what _they_ need to do, though.

l.

If Visual Studio 2005 suffices, I'd give it a try.

Propad
 
T

Terry Reedy

lkcl said:
sorry, terry, you deleted a bit too much context :)

I was referring to this at pyjd.org:

Pre-built amd64 .debs are available for download, providing
pywebkitgtk-1.0, libwebkit-1.0-2 and libwebkit-dev, here:

* Download libwebkit-dev, libwebkit-1.0-2 and pywebkitgtk-1.0

and this
was my acknowledgement that a Windows binary is not trivial and that I
don't expect one from you after all the nice work you have done.

[compiling with mingw32]
why the python developers didn't include the patches, and keep them up-
to-date, isn't clear.

Mostly likely because no one who uses mingw32 has volunteered to become
the mingw32 Python developer who would update such patches to current
Python (now 2.6/3.0) and support them by responding to bug reports and
by upgrading them to 2.7/3.1 in the next few years.

Any system supported in core Python code with a set of #includes needs
*someone* who will support that set. If the supporter disappears and no
one else volunteers, the #includes become obsolete and get deleted.

Terry Jan Reedy
 
T

Terry Reedy

Propad said:
Is Visual Studio 2005 OK, or is some other compiler required?

I believe 2.4/2.5 used VS 2003 while 2.6/3.0 do (and 2.7/3.1 will) at
least officially use VS 2008. The free express version apparently
works. It is possible the extension extension modules compiled with
2005 have/will work. I would ask in a separate thread with VS 2005 in
the subject line.
 
O

Orestis Markou

Just want to say, thank you for a very enlightening writeup. You
should really post this somewhere that we can link to.
--
(e-mail address removed)
http://orestis.gr/




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.
 
D

David Boddie

i don't know if it _was_ detached from the layout, but it was
definitely still visible. see
http://pyjs.org/examples/gridtest/output/GridTest.html
for the example i was porting to pyqt4. each time i clicked "Next", a
new set of N,N would be _overlaid_ on top of the old ones, even though
i was doing removeItem().

Yes, it just sounds like you needed to delete the layouts after removing
them.

I might take a look later in the week if the code in there is runnable.

David
 
P

Paul Boddie

Just want to say, thank you for a very enlightening writeup. You  
should really post this somewhere that we can link to.

Is this not good enough for you...?

http://mail.python.org/pipermail/python-list/2008-October/511375.html

I don't see the Python mail archives going away soon, although there's
also the Wiki for updated and maintained documents.

Although using browser technologies for desktop applications is
interesting (and not new by any means), there are a few things with
regard to layouts which are very difficult with Web technologies (and
aren't getting any easier, either) but which are almost trivial with
classic graphical user interface toolkits, and of course there are
cases where the roles are reversed. I haven't really written any
classic GUI applications for quite some time, but I feel that it's
worth pointing this out.

Paul
 
L

lkcl

Just want to say, thank you for a very enlightening writeup. You
should really post this somewhere that we can link to.

orestis, thank you for the encouragement. i did post it on my diary:
http://advogato.org/person/lkcl/diary/523.html - i decided against
doing a full-blown article because i've been doing quite a _lot_ of
writing on advogato :) but i'm reconsidering. will post here if i do.

i note with interest your comments here:

http://orestis.gr/blog/2008/09/19/random-gui-toolkits-web-and-python/

whilst pyjamas and pyjamas-desktop are definitely cross-browser, cross-
desktop, cross-platform and can even be made to be cross-widget-set,
there isn't anything to substitute for _design_ ethos on a per-
platform basis. by that i mean, expectations of there being a "File"
menu on which the word "Quit" will occur, or, as you point out, mac-
user expectations of application behaviour.

l.
 
L

lkcl

Yes, it just sounds like you needed to delete the layouts after removing
them.


I might take a look later in the week if the code in there is runnable.

yeah, it is.

hello_loader.py is the main.... err.... um.... i just double-
checked, so i'd be able to advise you and... err... the problem i
described (with the GridTest) seems to have... gone away!!

*slightly embarrassed* :)

however, clicking too fast _did_ end up with fifty little windows of
text (!)

and the respect for text boundaries is definitely broken - shrink the
window to 300 x 400 with the kitchensink example (which is where i
stopped and moved to webkit, so all the _other_ examples prior to that
will work) and you'll see that the text in a column down the left hand
side end up all overlapping each other. so, you get to see the top
few pixels of each word.

if there's a way to enforce the displaying of text - for the _text_
to say "i need to be a total area of X in order to display my words.
if you make my width too small, i will _force_ my height to be larger
as i wrap the text".

just like an HTML <p> </p> does.

l.
 
L

lkcl

I was referring to this at pyjd.org:

Pre-built amd64 .debs are available for download, providing
pywebkitgtk-1.0, libwebkit-1.0-2 and libwebkit-dev, here:

* Download libwebkit-dev, libwebkit-1.0-2 and pywebkitgtk-1.0

thanks for confirming, i thought so.
and this

was my acknowledgement that a Windows binary is not trivial

ha ha - i found that out :)
and that I
don't expect one from you after all the nice work you have done.

thanks.
[compiling with mingw32]
why the python developers didn't include the patches, and keep them up-
to-date, isn't clear.

Mostly likely because no one who uses mingw32 has volunteered to become
the mingw32 Python developer who would update such patches to current
Python (now 2.6/3.0) and support them by responding to bug reports and
by upgrading them to 2.7/3.1 in the next few years.

*nods head side-to-side*... yeahh, good point :)
 
L

lkcl

If Visual Studio 2005 suffices, I'd give it a try.

ok. let's change the subject....

it's bog-standard compile-procedure for webkit, under VS, but you
must add in the patch for the glib bindings.

you'll need a _hell_ of a lot of libraries. read this:
http://lkcl.net/webkit/cross-compile-gtk.notes.txt

and of course ignore mingw32 bits - use it to track down the locations
for the various libraries in win32 form, including the .a files.
you'll need cairo, gtk, gdk, libxml, libxslt and libicu. ibm's moved
that on to version 4 and it's compiled up for win32 already.

do make yourself known to the #webkit-gtk team on irc.freenode.net and
ask for their help.

_do_ use the code i have at github.org, use the 16401.master branch, i
do not recommend attempting to use the latest svn plus the patch at
bugs.webkit.org because alp has moved things on a bit and i haven't
the time to update to the latest svn and redo the patch.

http://github.com/lkcl/webkit/tree/16401.master


then, once you have a libwebkit.dll, you'll be in a position to
recompile pywebkitgtk for windows. this should be very very
straightforward: there's nothing out-of-the-ordinary, other than you
must patch it, use the last download / attachment from here:

http://code.google.com/p/pywebkitgtk/issues/detail?id=13

i'm not _entirely_ sure how you go about compiling a c-based python
module under windows, esp. one that requires autoconf: perhaps someone
else here can advise, but if i was to be doing it, i'd start off by
installing MSYS, locating a windows version of autoconf and gnu make
and friends, and seeing how far i could get from there.

you'll definitely need a windows version of python-gtk2 first, though,
which will, aside from anything, give you lots of clues as to how to
go about compiling pywebkitgtk - it's exactly the same principle.

the reason why you'll need python-gtk2 is because of codegen.py - that
is used to turn the webkit.defs into a webkit.c file.

good luck! :)

l.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top