GUIs - A Modest Proposal

S

Stephen Hansen

yes. that's effectively what pyjs applications are about: as much
HTML/CSS as you can stand, then _absolute_ pure javascript from there-
on in... only using a compiler (python-to-javascript) so as not to go
completely insane - and, from the rest of your message, i _know_ you
know what i'm talking about, there :)

Yeah. It sounds very interesting. I just wish it, like, somehow bundled
webkit cross-platformly. :)
to be absolutely honest, i very rarely even write my own widgets: i
advocate that people, myself _especially_ myself included, perform
literal line-for-line translations of GWT widgets from java to
python. why? because, again: on the basis that google have tons of
money to put into GWT widgets, doing full regression tests, and have
thousands of users, they can afford to get the widget right across all
the browsers. ergo, why duplicate that effort - just code-translate
it verbatim!

oh, btw, that's turning into quite a powerful project on its own: the
goal is to have a fully automated java-to-python translator!

http://github.com/thoka/java2python

Somehow this is getting perverse. Java, to Python, to JavaScript. It
just sounds sort of incestuous. :)

But also worth looking into for my next web project.
we've found that there's a third "hybrid" case, and it's hinted at
through RIA javascript libraries such as extjs: a traditional GUI
model *implemented* as a web app.

so those RIA JS libraries are not "vs", they're _both_. except...
javascript has its own headaches, so that's why both pyjamas and GWT
remove _those_ headaches, by using language translators.

Well, yes. I have some experience with extjs (and making some pretty
fantastic real-world seeming apps on the web with it), and yeah,
removing Javascript headaches is a very interesting goal. (Pet peeve to
end all pet peeves: trailing commas in objects breaks IE. I always leave
trailing commas, always, in Python code: makes adding stuff easier
later. And I can't shake doing it in my javascript instinctively).

The current project occupying my time involves a fairly complicated mix;
on the server-side we have Pylons, but its interfacing with an external
application server, so about half of the Pylons layers are "outsourced"
(i.e., data and model access).

Then the web interface is ExtJS. Its just getting very, very -- ungainly
from a maintenance point of view. Maybe on its next iteration I'll look
into pyjamas.
oooOo. that's _very_ interesting to hear. i'd assumed that there
wouldn't be anything "beneficial" that wx would bring to the table, by
using gtk. ha. that might be worthwhile doing a pyjd-wx port, then,
after all. hmm.

Well, I may have overstated it a little bit by mistake.

wx does not require you use this model, and it does not do it on its own
-- you do have to "design" the flow a little bit.

wx has two separate containment hierarchies. The first is a
hierarchical, parent->child relationship. This is what a lot of people
think is its layout: but its not. It has nothing to do with layout, but
instead its more about event propagation. Then again it can *affect*
layout (you can't lay out the child of PanelA in PanelB).

But the real layout system is based on the sizers. Every "container"
control can have a single sizer. This sizer can contain any number of
the children of the parent. It can choose to lay them out in any number
of basic ways: the horizontal box, vertical box, grid layout, flexgrid
layout, then a couple specialized ones. Each individual object in the
sizer can have any number of flags, such as align this way or that, add
this amount of border, and if the object should be expanded to fill the
available opposite-space. (This is complicated: basically, if you have a
Horizontal Box controlling a window, and you add three items into it,
they'll sit next to each other and not fill out either the horizontal or
vertical space. But if the first item is set to 'expand', then it will
fill out all the available *vertical* space that the sizer is allowed to
manage).

Then comes the most important setting: the proportion option. Here you
determine how much of the available primary space each given object
gets. If you have three objects, all proportion 1: then all will share
the horizontal space evenly, expanding to fill all available. If one is
2, and the others have 1... then they'll all expand, but one will have
2:1 of the size.

Now, while the sizers are making all these decisions, they are taking
into account various constraints. You can set minimum sizes, maximum
sizes, 'best' sizes, and these'll be taken into account when laying out
and 'flowing' the user interface.

The key comes in that you can nest sizers. So, you add two objects to a
Horizontal Box Sizer, and the second is a Vertical Box Sizer. If both
are set to share all available space, the right one will get half the
screen. But it then can have all kinds of objects added to it, and
they'll be lined up in a vertical line on that.

Ahem. /Rant. I'm not saying its the best layout system in the world, but
like your DOM/HTML example -- its resolution independant (and
cross-platform), so you can start resizing things and changing the
window size and it all reflows things as the window resizes. Lots of
toolkits can do that, but I just really find the sizer approach both
flexible and very powerful to achieve very usable interfaces. (And its
very web-like, except the semantic difference of the two hierarchies)
but - allow me to write a quick app which does what you ask:

[snip implementation]

It looks very interesting: don't get me wrong, pyjamas (and Desktop in
particular) look to be in some contexts a compelling sort of tool. I'm
not entirely sure I comprehend how it works underneath so don't yet know
if it'd ever be something I'd be able to use (I don't understand where
this py->js transition is happening

command-line tool. takes python as input, does "imports"; anything
it can "import" it also translates and adds to the output; total is
spewed forth as a pure javascript app.

from there, you just... open it up in a web browser, just like you
would any other HTML/CSS/Javascript app.

Well, I got that much; I more meant the Pyjamas-Desktop thing. It makes
regular "seeming" application/client-based user interfaces, right? Are
those all entirely, once run, 100% JavaScript (post-compilation)?

If so, Desktop at least isn't useful to me. :( I can't access omniORB
with it :)

But for a web app, it might be.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFoNrAAoJEKcbwptVWx/l8EkH/0Z+RuhVumJYW4j+ssyMIj7e
hQrwth9qzunWcJjzI9N2V7NwI8kMHgYrjA84GZ2SoE75t40HjccSXGhEWfiCOgpT
RL+NK0Cotdoqp1UzWJFhqPWYgZ5NxngFA0E4fQnAjvFzZPrGliIGolt8Q2nB/WNz
Yb1k2B2nnFW3SBDfY2IwMB0qIq9xYDBBogGxl7VmnAovVXe1B0VNZB0kgo/DAxGt
ScInTzOmuO04O5aaUAb5uFX/+Uqr3scXuL8ig2HwPsU1IdyuzhUOggG52VIeI9+7
sq6VDQ3br1MoiL4q00oYYSWRWFcic/uvBBKvLiK+d+BYt527lCzW7Rx5INt4JZ4=
=1liT
-----END PGP SIGNATURE-----
 
S

Stephen Hansen

from thereon in, you DO NOT do *any* HTML page "GETs": it's a one-
time static HTML/JS load, and THAT's IT.

the only further interaction that we recommend is first and foremost
JSONRPC (and so, out of the 30 or so pyjamas wiki pages, about 10 of
them involve HOWTOs for interacting with django, pylons, web.py,
web2py, twisted and so on) and the second one, because you have to, is
HTTP POST of Multi-Part FORMs.

AJAJ ftw.

(Yes, how you describe the situation is how I develop web apps, minus
the pyjamas and plus the wtf-javascript for the client side)

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFoQXAAoJEKcbwptVWx/loeoH/27kS+TDdapuE6+NLQUw8Ymd
xGJQm0lDn46PvW9ZMereLmFmYzMTbP7mpyCyvOOgq9cRSin77hZYHk3vLlXDArOl
pgu/j/nGRmInaiZiUiFf9BtXNnf2GWSmnRu6l9pdgKUffZKverH1t5G/1gZr+GDx
UKskmNr02E1njR+ADvJ0ZQNfWj7IuSj1rcmyK6j79xhLSjX2x1LC2Yn109iQpUP2
Q6XW7rqRTThl/MjCZHJOg+dlCL85DaiUhEiQN5Llop7y7In0ZmrAk5bMCEb5W+Eq
N7GlADkf8kO3u6W0Hy2FnPCC6kD7dUkPfbyO4I5azH9WJpWer1gSXcnsgjjStZY=
=uxwX
-----END PGP SIGNATURE-----
 
L

lkcl

Yeah. It sounds very interesting. I just wish it, like, somehow bundled
webkit cross-platformly. :)




Somehow this is getting perverse. Java, to Python, to JavaScript. It
just sounds sort of incestuous. :)

But also worth looking into for my next web project.




Well, yes. I have some experience with extjs (and making some pretty
fantastic real-world seeming apps on the web with it), and yeah,
removing Javascript headaches is a very interesting goal. (Pet peeve to
end all pet peeves: trailing commas in objects breaks IE. I always leave
trailing commas, always, in Python code: makes adding stuff easier
later. And I can't shake doing it in my javascript instinctively).

The current project occupying my time involves a fairly complicated mix;
on the server-side we have Pylons, but its interfacing with an external
application server, so about half of the Pylons layers are "outsourced"
(i.e., data and model access).

Then the web interface is ExtJS. Its just getting very, very -- ungainly
from a maintenance point of view. Maybe on its next iteration I'll look
into pyjamas.



Well, I may have overstated it a little bit by mistake.

he he. rats!
wx does not require you use this model, and it does not do it on its own
-- you do have to "design" the flow a little bit.

wx has two separate containment hierarchies. The first is a
hierarchical, parent->child relationship. This is what a lot of people
think is its layout: but its not. It has nothing to do with layout, but
instead its more about event propagation.

oh crap, yeah, i forgot about that. event propagation rules. darn
it. y'know what? forget it - i might as well, seriously, help
implement an entire modern web browser in python, and use that.
Ahem. /Rant. I'm not saying its the best layout system in the world, but
like your DOM/HTML example -- its resolution independant (and
cross-platform), so you can start resizing things and changing the
window size and it all reflows things as the window resizes. Lots of
toolkits can do that, but I just really find the sizer approach both
flexible and very powerful to achieve very usable interfaces. (And its
very web-like, except the semantic difference of the two hierarchies)

*sigh* i think i'm just going to have to try it, just to find out. i
can't have me saying "all desktop widget sets are rubbish!" if i
haven't _actually_ gone and done my homework, can i?

Well, I got that much; I more meant the Pyjamas-Desktop thing.

ohh, right - sorry.
It makes
regular "seeming" application/client-based user interfaces, right? Are
those all entirely, once run, 100% JavaScript (post-compilation)?

nope not in the slightet - the javascript is literally out the
window, bypassed entirely. that same application you had which was
the input to the pyjsbuild compiler "pyjsbuild Hello.py"? you just...
run it! just like a pygtk2, pyqt4 or python-wx app:

python Hello.py

in the background, what happens is that the "shim" library DOM.py
(which is the one with the most javascript in it) is *replaced* by an
alternative which is pure python, and which uses the COM wrapper
(MSHTML), or the XPCOM wrapper (XulRunner) or pygobject (pywebkitgtk)
to *directly* do the *exact* same equivalent jobs of the JS-converted
code... only this time, now "direct" in python to the exact-same-named
DOM functions, properties etc. the whole damn hog: everything that's
in JS in a web browser, it's accessible via python bindings to MSHTML,
XulRunner or (a hacked version of) pywebkitgtk.

but, as a developer/user you _do_ not need to know that - all you
need to know is: the python code runs, it throws up a window, the
application's in it, it's on the desktop, it's not a web browser,
that's the deal.

If so, Desktop at least isn't useful to me. :( I can't access omniORB
with it :)

yeahh, you can... but then if you actually wanted it to be a web app
as well, you'd be hosed (unless you want to create a browser plugin /
extension which can talk omniORB!)

what we typically recommend is that _even_ though you're going to run
the application "desktop" - as pure python - you still use JSONRPC [or
XmlHTTPRequest if JSONRPC is overkill]. so, _even_ though it's a
desktop application, you still run a local 127.0.0.1 web service (even
python -m SimpleCGIServer.py will do the job!)

rick's article is highly illustrative on all these points:
http://www.ibm.com/developerworks/web/library/wa-aj-pyjamas/

there are kiinda good house-keeping reasons for taking this approach:
it forces a developer to break the app along MVC-like lines. that
service is _only_ going to be serving data; you could even write unit
tests using a python-based JSONRPC client, and so on:
http://pypi.python.org/pypi/lovely.jsonrpc
http://lkcl.net/jsonrpclib.tgz

i think rick points out these json clients or better, and demos how
to use them.

so it's not as "forced" a development approach as it seems.

but, yeahh, if you absolutely must, you can use "standard" python
libraries - the only thing you'd have to watch out for is that
anything you call musn't take too long, because you're in the middle
of the (effectively single-threaded) GUI loop at the time. this is
another very good reason for taking the client-server approach _even_
though you'd be running the server on 127.0.0.1.

all the methods by which you would have to deal with that GUI loop
problem have to be asynchronous _anyway_... aaand, what the heck, why
not just go with the flow and use the pyjamas.HTTPRequest or
pyjamas.JSONService recommended services, neh?

l.
 
L

lkcl

 all the methods by which you would have to deal with that GUI loop
problem have to be asynchronous _anyway_... aaand, what the heck, why
not just go with the flow and use the pyjamas.HTTPRequest or
pyjamas.JSONService recommended services, neh?

sorry to be adding stuff after-the-fact, but this is so ironic and
nuts i have to point it out. underneath pyjamas.HTTPRequest and
pyjamas.JSONService, that's XmlHttpRequest... no not XmlHttpRequest
from javascript/web-browsers: XmlHttpRequest _from python_! in the
MSHTML port, it's actually a COM interface wrapper around the
functions found in MSXML3 or MSXML6 DLL :) and yeeees, it actually
works, in exactly the same way, identical in virtually every respect
across all the pyjd ports (with the exception of some bugs in
XulRunner/XPCOM), as the exact same javascript object found in web
browsers, with the exact same functions, event-handling callbacks and
so on.

as an aside to that: i don't recommend you go looking into it (400
comments+ on a bugzilla...), but the development of the glib/gobject
bindings were a total nightmare. not from a technical perspective,
but from what can only be described as ... well, one of the developers
decided quite early on that i must be some sort of egomaniac, and that
i had to be "taught a lesson". this "lesson" involved finding any
excuse, method or rule (existing or made up) to jeopardise the webkit-
gtk glib/gobject bindings. it didn't matter what it was - the answer
"no" _would_ be found. i call this "technical bullying".

in the case of the XmlHttpRequest functionality, the justification
was simple: "there are perfectly good gtk networking libraries out
there. bug closed, that's the end of it. I, Mark Rowe, Have
Spoken" (implication: **** off you dip-****).

it took one of mark rowe's own colleagues, maciej, to point out that
the lack of XmlHttpRequest functionality for the objective-c webkit
bindings had forced at least one iPhone development team, to his
knowledge, to write an "XmlHttpRequest" look-alike - in objective-c!
and that, furthermore, _without_ the bindings to "real"
XmlHttpRequest, that reimplementation's effectiveness was severely
curtailed. maciej pointed out that the "real" XmlHttpRequest has
access to "onload" event notification, XSS security, and all the other
stuff that makes XmlHttpRequest so powerful: interaction with the web
browser engine and its internal events, workings and state
information.

now multiply that one experience by 300+ DOM objects, 2000+ W3C DOM
functions and 20,000 W3C DOM properties, all of which had to have glib/
gobject bindings, and you can see how easy it was for one egoistic
webkit developer to jeapordise the chances of success of the
pywebkitgtk project, based on their "superior technical knowledge"
and, if that wasn't superior enough, judicious use of turning a blind
eye to legitimate technically sound arguments.

the _only_ reason that, after nearly 18 months of delay, webkit now
has _partial_ glib/gobject bindings that are useless as far as pyjamas-
desktop is concerned, is that a) i wore them down: the amount of time
being spent "countering" eevery single fucking argument was just far
too time-consuming b) i embarrassed them: the implications of being
banned from webkit and the manner in which that censorship was carried
done became shameful to them c) this is the important bit: lots of
people *other than me* have been clamouring for webkit-glib/gobject
bindings.

so they _had_ to put the glib/gobject bindings in, after all that
effort spent fighting tooth and nail to prevent it... and not having
access to the key developer who worked on it (because of censorship)
it's been a bit of a bitch for them, and it's only about 80% complete,
after 6 months (the initial work only took 10 weeks!)

upshot is: if anyone wants python bindings to webkit including the
full suite of DOM objects, you're going to have to get onto webkit-dev
mailing list and bitch like a trooper. nicely, mind :) the more
people ask (and raise bugreports about it), the less they can say
"no".

l.
 
S

Stephen Hansen

oh crap, yeah, i forgot about that. event propagation rules. darn
it. y'know what? forget it - i might as well, seriously, help
implement an entire modern web browser in python, and use that.

In practice its a non-issue; the parent->child hierarchy with rare
exception mirrors the sizer layout hierarchy, the latter is just more
dense. And only some kinds of events propagate by default.

Its really not that big of a deal.

If you want to hear when someone clicks a button, you can bind to that
button an event handler (very like JavaScript). Or, if you want, you can
bind a handler to the window, and catch -all- button events (*), and
decide what you want to do based on what button was pressed. I almost
never do this.

Only "command" events propagate. Those that represent a discrete user
action: a button press, clicking on a radio button, hitting 'enter' in a
text control, a right click. Stuff like that. But you don't have to
treat it like a propagating event-- I almost never do-- and you can
instead just add a handler onto the object itself. The rest of the more
abstract events (mouseover, etc) you have to bind the handler to the
object itself.
nope not in the slightet - the javascript is literally out the
window, bypassed entirely. that same application you had which was
the input to the pyjsbuild compiler "pyjsbuild Hello.py"? you just...
run it! just like a pygtk2, pyqt4 or python-wx app:

Ahh. Interesting.
If so, Desktop at least isn't useful to me. :( I can't access omniORB
with it :)

yeahh, you can... but then if you actually wanted it to be a web app
as well, you'd be hosed (unless you want to create a browser plugin /
extension which can talk omniORB!)

what we typically recommend is that _even_ though you're going to run
the application "desktop" - as pure python - you still use JSONRPC [or
XmlHTTPRequest if JSONRPC is overkill]. so, _even_ though it's a
desktop application, you still run a local 127.0.0.1 web service (even
python -m SimpleCGIServer.py will do the job!)

rick's article is highly illustrative on all these points:
http://www.ibm.com/developerworks/web/library/wa-aj-pyjamas/

Hmm. Depending on just how rich of a UI is possible, this is a slightly
compelling idea. Right now, I have to essentially maintain two separate
code-bases: the desktop client and the web application. In my scenario,
both are actually lightweight (though not truly thin) clients to a
master application server existing Elsewhere, that does the heavy
lifting and manages all its users.

Being able to take a code base and provide it to users as a
traditional-seeming desktop application that works desktopy for them,
with-- it sounds like-- two separate processes, one which is Python and
is "serving" data, and more importantly accessing the MCP and getting
instructions and doing its "lightweight" local lifting-- and another
which is just a UI that communicates to that local server?

Then one would run basically the same code on a server to allow remote
access on some internet-accessible server, that sounds like what you're
implying is possible? This time the server is still there, but the
client UI is converted into pure JS and shipped to the persons machine.

That sounds too good to be true. I sort of have to be reading too much
into what you're saying.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFphaAAoJEKcbwptVWx/lPAwH/2guC6exONS8bjtYi5g9oSLD
U5D8cDQBlj4mPp947/4pXOj04jnjK1RtDGmebnOC3clkXw7IlM6ltI1zgwro1P3y
CIhAAWD/Q+e7TloQShe2eGigX8vLlF60IFioMuukZsXVW6nNMiJW7du9e/wekYr2
G/MQ8BBl5oD3TCQOTLejvQqS4ffhJiNeZRbY/fOjaTIoIoZx3cXR2zRUY6pMuhkl
FncP4zyFMS0DeO/FoMnfqPuLOgJpQVf2t6ZVBRyiCGl7Hdp9bCwSP+eAzYN4ew7I
c2fowhA0b5BRG+C1r1lRZMA6ohuiGSFfW2V0oe2PvBi5ZkPhN0YSM69NEb355xk=
=BhyW
-----END PGP SIGNATURE-----
 
L

lkcl

Yeah. It sounds very interesting. I just wish it, like, somehow bundled
webkit cross-platformly. :)

_that's_ a long story - a brief insight into 8 months of hell i
posted in another message on this thread...
Somehow this is getting perverse. Java, to Python, to JavaScript. It
just sounds sort of incestuous. :)

oh i haven't mentioned the javascript-to-python converter yet, have
i? *lol*. am still looking for a good BNF / parser in python, for
that one.
Well, yes. I have some experience with extjs (and making some pretty
fantastic real-world seeming apps on the web with it), and yeah,
The current project occupying my time involves a fairly complicated mix;
on the server-side we have Pylons, but its interfacing with an external
application server, so about half of the Pylons layers are "outsourced"
(i.e., data and model access).

Then the web interface is ExtJS. Its just getting very, very -- ungainly
from a maintenance point of view.

ooh. ouch. we've had people wanting to wrap extjs in pyjamas. i
told them NO don't for god's sake do it. it's _hundreds_ of thousands
of lines of javascript; looking at the GWT-EXTJS wrapper, the
"startup" code in javascript is a whopping 8,000 lines (which was more
than the entire pyjamas codebase at the time!) and the rest of the
"wrapper" code i believe is some 80,000 lines of java.

then there's the issue that, apart from all that code to maintain,
you now have a whopping great 2.5mbyte javascript dependency, where
you'd need, if there was a bug in that, an expert javascript
programmer...

so whilst pyjamas UI widgets are somewhat at the level of "extjs
0.000001", at least there is http://puremvc.org (which yes, that
_does_ compile to javascript cleanly!) which you can combine with e.g.
the Grid Widget and a few more prettifying widgets, in order to create
the kinds of looveliness that is extjs.
Maybe on its next iteration I'll look
into pyjamas.

mmm, that leaves you with an all-or-nothing approach. there's a
trick you could do, which involves using a pyjamas ui Frame widget,
where you could convert the site one bit at a time. that's been done
before now.

if you're already using an AJAX approach in the back-end server
(which it sounds like you are) then you'll be much much further ahead
than many pyjamas converts: all you'd need to do is reimplement page-
by-page the front-end widgets.

ok gotta go, baby's dragging me away.

l
 
E

Ethan Furman

lkcl said:
this is getting sufficiently ridiculous, i thought it best to
summarise the discussions of the past few days, from the perspective
of four-year-olds:


AH hahahahahahahahahahahaha
 
R

rantingrick

Stephan speaking of Wx geometry managers...
Ahem. /Rant. I'm not saying its the best layout system in the world, but
like your DOM/HTML example -- its resolution independant (and
cross-platform), so you can start resizing things and changing the
window size and it all reflows things as the window resizes. Lots of
toolkits can do that, but I just really find the sizer approach both
flexible and very powerful to achieve very usable interfaces. (And its
very web-like, except the semantic difference of the two hierarchies)

Oh Stephan i strongly disagree with that assessment. Tkinter blows Wx
away with it's simultaneousness powerful AND elegantly simplistic
geometry managers, grid, pack, and place. If you have not used them to
any extent i strongly encourage you do so before boasting on the
superiority of Wx geometry management. It's like night and day really.
Wx is very ugly in this respect, again due to fact it has a C base
developer pool.
 
R

rantingrick

 ah.  again, the "recommended" pyjamas development model vs the
"standard" development model comes to the rescue, here.  in a pyjamas
app, the app loads ONCE and ONLY ONCE, as one whopping great
javascript behemoth which can be somewhere around 2mb if the original
python (pyjamas) source is around... 15 to 20,000 lines of code.

Hmm, we have a Python API already worked out. I wonder how much
trouble it would be to get pyjamas into this API. The SketchUp folks
are just busting at the seems for a more developer friendly web dialog
environment and SketchUp WebDialogs just ain't cutting the mustard
(more like the cheese!). Let me know if you may interested in
spearheading this endeavor as i can offer my motivational skills to
push the product and help you work out a friendly API!
 
S

Stephen Hansen

Stephan speaking of Wx geometry managers...


Oh Stephan i strongly disagree with that assessment. Tkinter blows Wx
away with it's simultaneousness powerful AND elegantly simplistic
geometry managers, grid, pack, and place. If you have not used them to
any extent i strongly encourage you do so before boasting on the
superiority of Wx geometry management. It's like night and day really.
Wx is very ugly in this respect, again due to fact it has a C base
developer pool.

I am familiar with grid, pack and place.

Are you arguing from an API point of view, or a functionality point of
view? I have no interest in debating the Pythonisity of Tkinter's API to
wxPython's -- its pointless, neither are particularly Pythonic, and I've
never argued wx does not have an API difficulty and learning curve.

From a functionality perspective, "pack" and "grid" are both distinctly
less capable then wx sizers. In the simpliest of interfaces, they
achieve similar goals in similar ways: but the lack of proportional
sizing kills it for me, unless I've been long mistaken in pack not
having a proportional option. A combination of "fill/expand" and
"anchor" do most of everything else, though, that wx's flags and
alignment options.

I've no interest in talking about "place"; absolute positioning is
simply pointless to me.

Now, from an API perspcetive? I'll not debate the merits of which is
better, except that your conclusion of 'why' its 'ugly' and difficult
that its a C based tool, is wrong. The API difficulty comes from the
fact that "sizers" are separate from containers, and that individual
items added to them don't actually have any internal knowledge of their
sizer environment. This creates some cumbersome interactions. However,
this can be largely made easier (And vastly more Pythonic) by simply
basing wx.lib.sized_controls as the base.

Then, instead of explicit sizer tweaking, you do things like:

import wx.lib.sized_controls as sc

class MyPanel(sc.SizedPanel):
def __init__(self):
sc.SizedPanel(self, -1)
self.SetSizerType("horizontal")

b1 = wx.Button(self, -1, "OK")
b2 = wx.Button(self, -1, "Cancel")

b1.SetSizerProps(expand=True)
b2.SetSizerProps(expand=True)

You can rewrite something very similar in Tkinter, sure. And you'll have
shorter names, and maybe you can argue 'pack' is more pythonic then
'SetSizerProps', but debating API pythonicity is just uneventful.

My original comments were about function, not form. I mean, we're
discussing the DOM here. There's never been a more hideous designed API
in the history of API's.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFrr2AAoJEKcbwptVWx/lKCsIAIoD6e2km/MF4eJiF0352KF0
0FapFSwZdVQsmjf9iiI3Q/zeyPBEBu8HLv+ABifMhg1U8aS2HrkjRz2c6uTaBUXL
MHnUssZ9KRMdexxpKCP0TdBMVSlcEvfyT6U2/iUXoNVgP8GmlKBNNIiejRyOMXvD
zPUAWAAfw5vZkvlsbSa40uq34nqu8LcWgaC8j0HzwmcUwp2wLXtfME7DU+yaj2ed
ChYcRFIB+iIMunX+fN4rZ/hNCK4ocycrQ1sdkgiXeH2rIjOyhq0k931e1UFW2vxc
WuOKPgfX/LdvB7PT83PsQiYGl/FgLIEaHdZQpd6ssbN7juw95vTHUHZw0HGShv0=
=aTMl
-----END PGP SIGNATURE-----
 
A

AD.

HTML+CSS have some very strong advantages. Simplicity is not one of
them. Precision web design these days is a dark art. (Go center an image
vertically and horizontally in an arbitrary sized field!)

I agree, and I know that's a rhetorical question, but here goes....

(I have no idea whether this works in IE though)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-
strict.dtd">
<html>
<head>
<style>
div {
position: absolute;
border: 1px solid blue;
margin: 10px;
}
#one {
top: 50px;
width: 300px;
height: 300px;
}
#two {
top: 400px;
width: 200px;
height: 200px;
}
img {
position: absolute;
width:100px;
height: 100px;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="one"><img src="image.jpg" /></div>
<div id="two"><img src="image.jpg" /></div>
</body>
</html>
 
S

Stephen Hansen

I agree, and I know that's a rhetorical question, but here goes....

"Arbitrarily sized" was the key point ;-) In that, you set the sizes of
the div's explicitly. I wasn't clear in my rhetorical question; the size
is arbitrary because you have no control over it. You can do horizontal
center easy; just set margin-left and margin-right to auto (and be sure
to set display: block if you're not sure which mode you'll end up).
Vertical centering outside of a table cell is a right pain in the ass.

Like so: Create an HTML single image that sits dead in the center of
your screen when your browser is maximized. Then if you adjust your
browser to be half as wide, its still in the center. Just the new center.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFsQOAAoJEKcbwptVWx/lysAIAJ7cBoBcP0hrdo7vT9QlIQgF
jU1CtuFCRtIar0eQtGLGEuLFwyvSGCa0KdEv2DBSET5kH1l3D7d84+FMK2i8ghK9
AV0QutFS4R/5YJIKVcsLbKPvo29kzcvirxlAOKZTGNxpg+OLCnmqC5j70HLoJlTS
02JEm6ObetzkAO7YnT1BLS+S4CT+dVGezq2qp+zaMQMu+G+NDX7WOoxdaYx4Lx4v
g88aum/Te0HeG/uJTvskc2wPoISGSZ6bnQvFmEpXtdNlTNclE9P8SXTawzVbFZZr
nn1Oh1JooyzVD3EAr3hzj3l7mmWryo4RD7upnSrCvhAjSDtZe86vbtM6N94ak0k=
=1j++
-----END PGP SIGNATURE-----
 
A

AD.

"Arbitrarily sized" was the key point ;-) In that, you set the sizes of
the div's explicitly.

As I said to Ed, I think you missed why I included the exact same
image in two divs of different sizes. That was to show it was still
centered no matter what size the container was. It is even easier to
fit it to the browser window.
I wasn't clear in my rhetorical question; the size
is arbitrary because you have no control over it.       You can do horizontal
center easy; just set margin-left and margin-right to auto (and be sure
to set display: block if you're not sure which mode you'll end up).
Vertical centering outside of a table cell is a right pain in the ass.  

Like so: Create an HTML single image that sits dead in the center of
your screen when your browser is maximized. Then if you adjust your
browser to be half as wide, its still in the center. Just the new center.

Even easier than the first example:

(Yeah I know these are trivial and quickly get out of hand on a real
UI)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-
strict.dtd">
<html>
<head>
<style>

img {
position: absolute;
width:100px;
height: 100px;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: 1px solid red;
}

</style>
</head>
<body>

<img src="image1.jpg" />

</body>
</html>

Anyway, wasn't this supposed to be about Python :)
 
P

python

Anton,

Very nice.

As an aside: I don't think you need to explicitly set your image size,
eg. I found your examples worked well with the following CSS properties
removed from the img specification:

width:100px;
height: 100px;

Malcolm
 
S

Stephen Hansen

As I said to Ed, I think you missed why I included the exact same
image in two divs of different sizes. That was to show it was still
centered no matter what size the container was. It is even easier to
fit it to the browser window.

I didn't miss it at all; I just didn't accept (and still don't
-entirely-) that positioning within an explicitly sized div is the same
thing as one which has had a flow-determined size.

But! That said:
Like so: Create an HTML single image that sits dead in the center of

Even easier than the first example:

Very nice. And interesting. "position: absolute" there is a mystery to
me and seems to be key, I'm not sure entirely what it is doing to the
layout manager in that scenario, but it seems to do the trick.

Much, much, much Googling led me to try many things to get it just
right, and all bemoaned the lack of a solid way to vertically center:
all the while using essentially similar methods to horizontally center.

Anyways. :)

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEbBAEBAgAGBQJMFt4rAAoJEKcbwptVWx/lJScH8gLHRjA1JYz0nl3y4vo+FvWS
j6xOlkPMp/STcAdA9ALqi4YfTjosuIrSiCVsxo7vfPK/pU/jU9lqA5/ITb5BwFDK
gQh92Or7LL3mdNXCqld/ZZcxwDoU9Wv/IsiETaZbX4/A/MlTl/8X+2ZPlUc4g3dd
TcIlnIu218aWa7dvCegHarRWXrNlbWoDEi6EWE0j7TFEnV/MULC1KLcvZ9GDRRA1
jhBa1P9clVRcQMesPLy4DufpnHPlM9bBFrsypL/hpl/X4fuUPAiS+vKKyjt4FbQh
6kJaLEEzIcmq50ZyKunUG37Tpb/Z5107an1QBMngbPonLTqTJXpo96SDUI+WQA==
=z8v2
-----END PGP SIGNATURE-----
 
R

rantingrick

I am familiar with grid, pack and place.

Apparently not, read on...
Are you arguing from an API point of view, or a functionality point of
view? <snip>

I going to argue that Tkinter offers the most "elegant" interface for
geometry management. And i'll leave it at that.
From a functionality perspective, "pack" and "grid" are both distinctly
less capable then wx sizers. In the simpliest of interfaces, they
achieve similar goals in similar ways: but the lack of proportional
sizing kills it for me, unless I've been long mistaken <snip>

YOU HAVE BEEN LONG MISTAKEN MY FRIEND! :). It seems the answer was
right under your nose and like bad breath you failed to smell it. Here
is the first paragraph for the docs of place geometry manager...

"""The Place geometry manager is the simplest of the three general
geometry managers provided in Tkinter. It allows you explicitly set
the position and size of a window, either in absolute terms, or
relative to another window."""
I've no interest in talking about "place"; absolute positioning is
simply pointless to me.

That argument ceases to be "relevant". See the triple quoted text for
an explanation as to why it is irrelevant and based on ignorance.
unless I've been long mistaken in pack not
having a proportional option. A combination of "fill/expand" and
"anchor" do most of everything else, though, that wx's flags and
alignment options.

You can rewrite something very similar in Tkinter, sure. And you'll have
shorter names, and maybe you can argue 'pack' is more pythonic then
'SetSizerProps', but debating API pythonicity is just uneventful.

What is this fascination with "pack" all about Stephan? The "pack"
geometry manager is the least useful of the three. Grid is your most
useful "all around" manager for laying out complex widget displays.
However that fact is not obvious to most Tkinter noobs because they do
not know about the "rowconfigure" and "columnconfigure" options that
allow for dynamic resizing of widgets within a container based on a
weight factor. There are also options for "sticky" behavior. The
following is my suggestions on when to use and *not* to use grid,
pack, and/or place.

GRID: Try to use grid for almost everything because it is the most
versatile of the three. However there are specific corner cases for
pack and place. Also never use grid and pack within the same
"container" widget or you'll cause Tk to lock up. You *can* however
use both managers in the same application as long as the widgets you
call "pack" and "grid" for do not share the same parent. Also like i
mentioned before you can get a dynamic resizing behavior on *any* or
*all* cols and rows by calling "parent.rowconfigure(weight)" and
"parent.columnconfigure(weight)". Use a weight of 1 to get full
elasticity ;). We all could use a bit more elasticity, no?

PACK: Only use pack if you have one widget and you wish it to fill
it's entire parent OR if you are stacking widgets in a horizontal or
vertical alignments (like a toolbar). This is where pack really
shines!

PLACE: Offers absolute and relative placements of widgets. Place will
not be used often but most of it's functionality can not be reproduced
with the other two options. Take for example the masks that are part
of a notebook widget, or placing a small button in the top left corner
of a frame or whatever...

The only people who like Wx geometry managers are the same who have no
experience with Tkinter's beautiful geometry managers. I encourage you
to investigate them for yourself. If anyone needs help feel free to
send me a private email or ask here on c.l.p.
 
R

rantingrick

From a functionality perspective, "pack" and "grid" are both distinctly
less capable then wx sizers.

Are you just flapping your gums or can you prove it Stephen? I will
accept any "Pepsi Challenge" you can muster in Wx code and echo that
same capability using Tkinter[1] in what will be no less than elegant
simplicity. So bring it on baby!

[1] But please, make sure to post code that will run as-is. The last
block of wx code you posted is missing an application instance and
will not run without modification. There are noobs watching and we to
provide code that can be used to teach!
 
S

Stephen Hansen

"""The Place geometry manager is the simplest of the three general
geometry managers provided in Tkinter. It allows you explicitly set
the position and size of a window, either in absolute terms, or
relative to another window."""


That argument ceases to be "relevant". See the triple quoted text for
an explanation as to why it is irrelevant and based on ignorance.

I didn't make an argument, so it can't be relevant or not. It remains
pointless.
What is this fascination with "pack" all about Stephan? The "pack"
geometry manager is the least useful of the three. Grid is your most
useful "all around" manager for laying out complex widget displays.
However that fact is not obvious to most Tkinter noobs because they do
not know about the "rowconfigure" and "columnconfigure" options that
allow for dynamic resizing of widgets within a container based on a
weight factor. There are also options for "sticky" behavior. The
following is my suggestions on when to use and *not* to use grid,
pack, and/or place.

I wasn't aware of [row|column]configure, no: however, I am dubious of
how it directly applies.

Consider this relatively simple user interface layout:
http://ixokai.io/get/layout-grid.jpg

In this context, we have two principle columns, A and B. A has a set
size, B grows to fill the rest of the dialog.

Inside of A, there are four items in a vertical line. The bottom which
takes up half of the total vertical space (poorly drawn, trust me, F
should be half :)), and the top three share the rest.

Inside of B, G is one third the size of H.

The layout should fully resize itself as the window is resized.

How would you implement that in tkinter? It sounds like you'd have a
grid with a pair of one-column grids, which is slightly bizarre seeming.
The only people who like Wx geometry managers are the same who have no
experience with Tkinter's beautiful geometry managers. I encourage you
to investigate them for yourself. If anyone needs help feel free to
send me a private email or ask here on c.l.p.

And exactly what's so great about it? All of the things you said it can
do, wx can do easily.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFuhlAAoJEKcbwptVWx/lek0H/jvL0KRqE9fS8ua5bXf2xApS
zDQZej2nDF09kF76KyS7HqWoGoh8Ms0Mm8PyGCgt4TJE9KJqEapRHB+jTqQo/p/q
JJIJ/gX2FrixHJri/owsMerWErLq/Yf7fnhdGqQxsjSL3in41vbsrlC2f7+20V9+
uLOIC9t9kPIHuR4EhYsmagwjFS1hfybwrQEs/mK56HDZTOdI9uJmBiTu4XU7oYTr
Sd9JHBGQOU608XfE8jMfiP+sjDLeVApc196FAOQXODkJRvR1N9pl02XH+SJhIeNF
X45EQCx6+/fMYLndmcSd1B3UkACgFMtIttekSVJDcuhDowSJc2mhcruUTBtCePI=
=84V6
-----END PGP SIGNATURE-----
 
S

Stephen Hansen

[1] But please, make sure to post code that will run as-is. The last
block of wx code you posted is missing an application instance and
will not run without modification. There are noobs watching and we to
provide code that can be used to teach!

No.


--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)

iQEcBAEBAgAGBQJMFuimAAoJEKcbwptVWx/lDIMIAJHFlYV1LrYNnoYwuyOpQLT6
zpO4vzVIlvHHxOcrKNw5avSP+9DSYHOiUUL0eSiMNXlMVz+utmrTkSYBcUMQj/+s
GWhgvuigLPJNcDcJ607eCs0ISk9tkw3LoGSjtaxANEgYrApqeEpfIHfM2BWZptMC
uweGfGG2cj32gPpohX+UT5vH8Zq1jrm9HVDbkNKdUu07JBA1vg85CDaqAcsEhKrR
L+n+QGOkcQao4cuRtZJFehK3RqnkRjKuK4nzsINYEMyro7aHUm5XXyyCjMczZ2f/
vtVn9z3uM0PO+RzPBhuNQYpCJPNzyegsy72yi7b8HuIFpwGjmhQr4UiK16v41Nw=
=FF8t
-----END PGP SIGNATURE-----
 
A

AD.

Anton,

Very nice.

As an aside: I don't think you need to explicitly set your image size,

Yeah, I only did that because I was assuming the image path would
actually be broken (and it was for me too) - it was just to 'simulate'
a 100x100 image :)
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top