Hooking things up in GUI application

R

Ryan Ginstrom

Apropos recent threads about GUI editors, coming from a Win32/WTL C++
background, I actually like the idea of being able to (easily) create GUIs
programmatically.

But I still see a lot of the same tedium: hooking up events to handlers, and
getting data into and out of dialogs. In C++, this is generally handled
through code generation and/or macros, but IMO these are brittle and ugly.

So my question: Is there a Pythonic way to make these tedious hookups easier?
 
J

James Stroud

Ryan said:
Apropos recent threads about GUI editors, coming from a Win32/WTL C++
background, I actually like the idea of being able to (easily) create GUIs
programmatically.

But I still see a lot of the same tedium: hooking up events to handlers, and
getting data into and out of dialogs. In C++, this is generally handled
through code generation and/or macros, but IMO these are brittle and ugly.

So my question: Is there a Pythonic way to make these tedious hookups easier?

I'm not sure any python gui has anything similar, but I hear cocoa users
raving about something called KVO.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
S

sturlamolden

Ryan said:
Apropos recent threads about GUI editors, coming from a Win32/WTL C++
background, I actually like the idea of being able to (easily) create GUIs
programmatically.

But I still see a lot of the same tedium: hooking up events to handlers, and
getting data into and out of dialogs. In C++, this is generally handled
through code generation and/or macros, but IMO these are brittle and ugly.

So my question: Is there a Pythonic way to make these tedious hookups easier?


If you use PyGTK (it also runs on Windows), you can design the GUI with
GLADE and then use libglade to import the gui as an xml-resource. You
have to write all handlers (you do anyway), but the GUI design becomes
entirely visual and the hookup becomes one single like of code. It
doesn't get easier than that. As a bonus you get an hardware
accelerated GUI (Cairo takes care of that, currently through OpenGL but
a DirectX backend is planned). I.e. a hardware accelerated GUI
represented as an XML resource. Isn't that Microsoft's next 'big thing'
codenamed 'Avalon'? I wonder where they got the idea.

This should illustrate the level of tediousness when using PyGTK:

import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade

class MyGUI:

def __init__(self):
win1 = libglade.GladeXML('mygui.glade','window1')
win1.signal_autoconnect(self) # hook event handlers, pass any
class or dictionary
win1.maximize()

def on_win1_destroy(self):
gtk.main_quit()

if __name__ == '__main__'
gui = MyGUI()
gtk.main()


You cannot make it less tedious in C++. Even if you use Visual Studio
and all sorts of 'wizards' to autogenerate code. Actually, if you do
use C, C++ or Ada, GLADE can autogenerate code just like Visual Studio.
But since an XML resource us much easier to modify and maintain, it is
not recommended.
 
S

sturlamolden

Ryan said:
Yes, I've tried something similar with wxGlade. Nice, but it doesn't seem to
remove the most tedious work -- hooking up handlers (although it does help
here, at the cost of some behind-the-scenes magic),

It does, there is just *one* line of code for hooking up all the
handlers:

win.signal_autoconnect(something)

That is one line of code for the entire window, not one line of code
for every widget in the window. Even if your window contains 100
widgets (buttons, sliders, menus, etc), this hooks up the handlers for
every one of them. You just call .signal_autoconnect once. This single
line of code does the job of all the message map macros you would write
in MFC, Fox and wxWidgets. signal_autoconnect does what it says, it
autoconnects the signal handlers. How can that be tedious?

Here is an advice: just be lazy. In particular:

* Don't create write a dictionary mannually and feed it to
signal_autoconnect. Many tutorials do that. It is silly: it is tedious,
it is superfluous bloat, and the job has in fact aldready been done.
Write a class instead. Guido has made sure every class has a
dictionary. Just make sure you have class methods with names
corresponding to the signals. Pass a class reference to
signal_autoconnect.

* Don't grab references for every widget out of the xml. I've seen done
that in many tutorials too. It is silly. Just ask the xml for a
reference when you need one. The xml resources will store the widget
references for you, you don't need to save them anywhere else. Storing
a hundred widget references as class variables is tedious and
superfluous work, and does not do anything except bloating and slowing
your code.

and getting data into and out of GUI widgets.

It does not save you the job of writing the GUI handlers! It saves you
the job of coding the GUI (delegate that job to a graphical designer!)
and hooking up the handlers. But you still need to *write* the
handlers.

That's the kind of boilerplate code that makes GUI
development a pain in my opinion -- the actual GUI design/layout isn't so
bad, especially with the spacer layout concept.

At least you get the GUI design out of the rest of your code. The
application logic still need to be there.
 
S

sturlamolden

Ryan said:
But I don't want to argue this point, just state that this isn't the problem
I want to solve. I really liked the idea of KVO/KVC in Cocoa that James
Stroud mentioned. That is what I am after, or something like that. If there
isn't anything like that, I think that it might be worthwhile to port it to
Python in some form. It seems at first glance that it would be fairly easy to
do.


I must admit I don't know the KVO/KVC in Cocoa so I had to look it up.
It seems they are accessing widget property values through text strings
called 'key values'.

In Python we have dictionaries, and dictionaries have 'keys' and
'values'. So it should be trvial to make a system where widget
attribute values gets stored in a dictionary. One would just have to
subclass the Python dictionary in order to send an update signal
whenever an item is written to.

In PyGTK we can create and access a label (static text) like this:

label = gtk.Label(str)
label.set_text(str)
str = label.get_text()

With 'KVC' (key value controller) design it could perhaps be changed
to:

label = gtk.Label(str)
label['text'] = str
str = label['text']

It does not save any lines of code. But it adds the possibility of
checking if a widget has an attribute through the 'in' operator. E.g.
to make everything red,

for widget in wigets:
if 'color' in widget:
widget['color'] = 0xFF0000

I am not sure how useful this would be.

Then there are 'properties', as one can find in Hejlsberg's creations
Delphi and C#. This is possible too, using Python properties, which is
merely a copy of Delphi properties. Then would have something like

label.text = str
str = labe.text

Still the amount of code remains the same. But perhaps the property
solution is the more readable. I don't know. I guess it is a matter of
taste.

http://developer.apple.com/document...ding/index.html#//apple_ref/doc/uid/10000107i
http://developer.apple.com/document...l/CocoaBindings/Concepts/WhatAreBindings.html


I don't use Wimp. These days, GTK looks good on Windows without Wimp.
But yes, GTK apps do get their own 'personality' (aka look and feel).
But so does many Windows applications. Microsoft Office has it's own
widget set, so does Mozilla, SPSS, LabView, Matlab, Internet Explorer,
etc. There is really not a consistent widget set, not even on Windows.
MFC/ATL/WTL use Windows GDI controls, C# use .NET/GDI+ controls, .NET
2.0 has controls slightly different from those in .NET 1.1 (e.g. menus
and toolbars), Visual Basic 6 had ActiveX controls that were similar
but not identical to GDI controls, Delphi (VCL) has its own controls,
so does Qt and FOX. The GUI consistency on Windows is an illusion. I am
not worried about the minor differences between GTK and GDI as long as
my program looks good.
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top