Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Jakub Piotr Cłapa
Doug Quale wrote:
Graham Ashton <[EMAIL PROTECTED]> writes:

On Wed, 2004-07-28 at 16:54, Doug Quale wrote:
Christian Robottom Reis <[EMAIL PROTECTED]> writes:

The issue I raised was "fear of namespace conflicts" that would be
introduced by this, but I think it's rather minor.
I don't actually have a strong opinion whether that change would be
good, bad or indifferent, so I was hoping someone smarter than me
could give some good arguments one way or the other :)
Smarter? Not me. But I have experienced it both ways. At work we've got
a rather large app (80k lines of Python), a fair chunk of which is GUI
code. We use libglade and some classes that wrap it up in a similar
manner to many of the examples posted here. The basic principle is that
your GUI class inherits from our own GWidget type thing, in which you
write lines like this:
  list_store = self._widget.treeview.get_model()
We had minor disagreement when we initially started with these classes
as to whether that was more sensible than the aesthetically cleaner:
  list_store = self._treeview.get_model()
We approached it conservatively and ended up with _widget everywhere. A
year later I can confirm that it's a right pain in the arse.
Thanks.  This is valuable experience.  I agree that name collisions
seem like an unlikely problem.
An interesting question is whether a glade controller (or widget
wrapper) class should automatically provide attribute bindings for the
glade widgets or if they should be specified explicitly.
I think Sridhar is automatically providing bindings to the widgets.
You can automatically provide the bindings by looking up the widgets
in __getattr__() in the WidgetWrapper base class:
class WidgetWrapper:
def __init__(self, ...):
   ...
def __getattr__(self, attr):
widget = self._xml.get_widget(attr)
if widget is None:
raise AttributeError, attr
setattr(self, attr, widget)
return widget
Another possibility is to make the programmer create these bindings
explicitly.  This could be done in __init__():
class MyController(WidgetWrapper):
   def __init__(self):
   WidgetWrapper.__init__(self, 'window1')  # window1 is in glade
   self._treeview = self._xml.get_widget('treeview1')
I use something like this:
	WidgetWrapper.__init__(self, 'window1', (
			'treeview1',
			'entry2',
			'other_names', )
		)  # window1 is in glade
It would bind all the widgets in the list as class attributes. It is 
simple but also doesn't clutter the class' __dict__.

--
Regards,
Jakub Piotr CÅapa
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Christian Robottom Reis
On Thu, Aug 05, 2004 at 04:37:45PM -0500, Doug Quale wrote:
> An interesting question is whether a glade controller (or widget
> wrapper) class should automatically provide attribute bindings for the
> glade widgets or if they should be specified explicitly.

My feeling is that "it depends". For the simplest UIs, then it probably
makes sense to allow grabbing widgets transparently via the widget
wrapper -- you don't want the newbie to have to declare everything under
the sun up there.

However, for more involved interfaces, there are a couple of issues:

- The documentation potential of indicating what widgets are special
  to your application. You have a hundred hboxes and vboxes, but
  that button and that entry and that label there are really the
  essential parts, and that's not always obvious -- you can have
  spacer labels, and content labels, for instance.

- The potential of specifying additional special behaviour for these
  widgets.

- The extensibility of the solution (which means adding behaviour --
  even unforseen behaviour -- to existing interfaces). For instance,
  you might want to start validating a certain widget in the future.
  That's easy -- implement a validation property and tie it into the
  "descriptor".

> Another possibility is to make the programmer create these bindings
> explicitly.  This could be done in __init__():
> 
> class MyController(WidgetWrapper):
> 
>def __init__(self):
>WidgetWrapper.__init__(self, 'window1')  # window1 is in glade
>self._treeview = self._xml.get_widget('treeview1')

This I feel lacks syntactic sugar. In Kiwi you just need to say

widgets = ["treeview1", ... ]

and any GladeView attaches them for you. This doesn't need to be a class
attribute (it's probably better off not being, since mutable class
attributes are Bad Ideas), but it needs to be intuitive and easy to use.

> How do readers of this group use widget proxies?  I know the Kiwi
> framework uses them extensively internally.

Yep. Note that proxies need a model to be able to set their data to.

All we do in that case is prefix the widget name (in the widgets list)
with a colon -- that means it's "proxied". This is a fairly constrained
setup and I'd be much happier if you could say 

Widget("entry1", proxy_for="name", validator=self.validate_name, ...)

but that's a bit more wordy. Maybe we could have proxy and proxy_for:

Widget("entry1", proxy=1, ...)
Widget("entry1", proxy_for="name", ...)

which would makes things quite easy to manage.

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 3361 2331
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Doug Quale
Graham Ashton <[EMAIL PROTECTED]> writes:

> On Wed, 2004-07-28 at 16:54, Doug Quale wrote:
> > Christian Robottom Reis <[EMAIL PROTECTED]> writes:
> > 
> > > The issue I raised was "fear of namespace conflicts" that would be
> > > introduced by this, but I think it's rather minor.
> > 
> > I don't actually have a strong opinion whether that change would be
> > good, bad or indifferent, so I was hoping someone smarter than me
> > could give some good arguments one way or the other :)
> 
> Smarter? Not me. But I have experienced it both ways. At work we've got
> a rather large app (80k lines of Python), a fair chunk of which is GUI
> code. We use libglade and some classes that wrap it up in a similar
> manner to many of the examples posted here. The basic principle is that
> your GUI class inherits from our own GWidget type thing, in which you
> write lines like this:
> 
>list_store = self._widget.treeview.get_model()
> 
> We had minor disagreement when we initially started with these classes
> as to whether that was more sensible than the aesthetically cleaner:
> 
>list_store = self._treeview.get_model()
> 
> We approached it conservatively and ended up with _widget everywhere. A
> year later I can confirm that it's a right pain in the arse.

Thanks.  This is valuable experience.  I agree that name collisions
seem like an unlikely problem.

An interesting question is whether a glade controller (or widget
wrapper) class should automatically provide attribute bindings for the
glade widgets or if they should be specified explicitly.

I think Sridhar is automatically providing bindings to the widgets.
You can automatically provide the bindings by looking up the widgets
in __getattr__() in the WidgetWrapper base class:

class WidgetWrapper:
def __init__(self, ...):
   ...

def __getattr__(self, attr):
widget = self._xml.get_widget(attr)
if widget is None:
raise AttributeError, attr
setattr(self, attr, widget)
return widget

Another possibility is to make the programmer create these bindings
explicitly.  This could be done in __init__():

class MyController(WidgetWrapper):

   def __init__(self):
   WidgetWrapper.__init__(self, 'window1')  # window1 is in glade
   self._treeview = self._xml.get_widget('treeview1')

or you can use a Python data descriptor

class GladeWidget(object):
"Data descriptor to bind glade widgets within a WidgetWrapper subclass"

def __init__(self, widget_name):
self.widget_name = widget_name

def __get__(self, ob):
return ob._xml.get_widget(self.widget_name)


class MyController(WidgetWrapper):

_treeview = GladeWidget('treeview1')

Christian pointed out the possibility of using different data
descriptors for different widget types.  This provides an easy way to
proxy the widgets. The proxy can decorate the widget with extra
methods and attributes.  It can also take extra arguments specific to
the widget type to specify radio button groups or other things.

_treeview = TreeViewProxy('treeview1', ...)
_up = ButtonProxy('up1', ...)

How do readers of this group use widget proxies?  I know the Kiwi
framework uses them extensively internally.
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Doug Quale
Lorenzo Gil Sanchez <[EMAIL PROTECTED]> writes:

> Talking about Gazpacho I'll share with you the way I plan to implement
> signal_autoconnect in Gazpacho:
> 
> 1. First check if there is a method named
> [on|after]_widgetname__signalname and if so connect the signal
> 'signalname' to the widget 'widgetname'
> 
> 2. Then check if the glade file has any signal definition (specified in
> Gazpacho signal editor) and then also connect these.
> 
> So basically, we wouldn't need the signal editor and all connection
> could be done from the source code of the user program. Why don't
> removing Gazpacho signal editor?. Well I can think on at least one
> scenario where it could be usefull: connecting two signals of two
> different objects to the same signal handler.

Good point.  I haven't often needed to connect signals from different
widgets to the same handler, but I've done it two ways when necessary.
Either do the connection by hand in the controller __init__() method
or simply delegate from one handler to the other by calling it.

Sometimes connection by hand in __init__() will be necessary anyway
because you want to connect to a widget that doesn't appear in the
glade file.  This happens a lot with textbuffers in textviews and with
treeview selections.  I think I remember reading a comment by Damon
Chaplin that he wanted to change glade to expose these widgets but I'm
not sure how that would work.

Gazpacho uses a checkbox on the Editor signal page to specify signal
connection using connect_after() instead of connect().  That doesn't
seem to allow specifying two handlers for the same widget, one to
connect and the other to connect_after.  Since this is rarely needed
and it's easy to do by hand I don't see the need to clutter Gazpacho's
GUI to allow doing this directly.
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Graham Ashton
On Thu, 2004-08-05 at 13:09, Sridhar R wrote:
> So you *manually* enter the handler name for each widget in glade
> signal editor right?  That's a bit inconvinient, if you want to add
> another callback, say--Add callback in glade signal editor and define
> the method in code.  GWidget [1] automates this.

Ah, I see. I hadn't gathered that bit. I can see the attraction for the
automation, but it had never even occurred to me do it.

Thanks.

-- 
Graham Ashton

___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Lorenzo Gil Sanchez
El jue, 05-08-2004 a las 16:09, Doug Quale escribió:
> Christian Robottom Reis <[EMAIL PROTECTED]> writes:
> 
> > On Thu, Aug 05, 2004 at 08:56:22AM -0500, Doug Quale wrote:
> > > Like Sridhar I also find it inconvenient to have to specify signal
> > > names in the glade file and then match them up in my code.  I think
> > > it's much easier to forget about setting the signals in the glade file
> > > and simply connect them based on method names.  
> > 
> > And to be honest, I'd appreciate it if Gazpacho could offer a way to
> > avoid even displaying this tab. It might be nice to have a "signal list"
> > button to display signals associated with a widget, but maybe that's
> > better dealt with via online docs.
> 
Talking about Gazpacho I'll share with you the way I plan to implement
signal_autoconnect in Gazpacho:

1. First check if there is a method named
[on|after]_widgetname__signalname and if so connect the signal
'signalname' to the widget 'widgetname'

2. Then check if the glade file has any signal definition (specified in
Gazpacho signal editor) and then also connect these.

So basically, we wouldn't need the signal editor and all connection
could be done from the source code of the user program. Why don't
removing Gazpacho signal editor?. Well I can think on at least one
scenario where it could be usefull: connecting two signals of two
different objects to the same signal handler.


> The signal list in gazpacho is very cool because it's nice to be able
> to see all the appropriate signals in one place.  The docs are good,
> but it's inconvenient to have to check the entire class hierarchy.
> 
> > Maybe Gazpacho should offer a way to browse John's reference manual in a
> > hypertext thingy. Or maybe I should stop giving people ideas .
> 
> An excellent idea.  Now all we have to do is contribute some code to
> do it 

Go for it!

Seriously, I think we don't have enought signal introspection in pygtk
(or even GTK) but generating xml files with that info and making
Gazpacho use them should no be hard.

Lorenzo

> ___
> pygtk mailing list   [EMAIL PROTECTED]
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Christian Robottom Reis
On Thu, Aug 05, 2004 at 09:09:22AM -0500, Doug Quale wrote:
> Christian Robottom Reis <[EMAIL PROTECTED]> writes:
> 
> > On Thu, Aug 05, 2004 at 08:56:22AM -0500, Doug Quale wrote:
> > > Like Sridhar I also find it inconvenient to have to specify signal
> > > names in the glade file and then match them up in my code.  I think
> > > it's much easier to forget about setting the signals in the glade file
> > > and simply connect them based on method names.  
> > 
> > And to be honest, I'd appreciate it if Gazpacho could offer a way to
> > avoid even displaying this tab. It might be nice to have a "signal list"
> > button to display signals associated with a widget, but maybe that's
> > better dealt with via online docs.
> 
> The signal list in gazpacho is very cool because it's nice to be able
> to see all the appropriate signals in one place.  The docs are good,
> but it's inconvenient to have to check the entire class hierarchy.

Yeah, definitely true. That's one thing GTK+ docs could deal with in a nicer
way -- showing inherited characteristics. I know epydoc does this
automatically and it's just so useful.

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 3361 2331
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Doug Quale
Christian Robottom Reis <[EMAIL PROTECTED]> writes:

> On Thu, Aug 05, 2004 at 08:56:22AM -0500, Doug Quale wrote:
> > Like Sridhar I also find it inconvenient to have to specify signal
> > names in the glade file and then match them up in my code.  I think
> > it's much easier to forget about setting the signals in the glade file
> > and simply connect them based on method names.  
> 
> And to be honest, I'd appreciate it if Gazpacho could offer a way to
> avoid even displaying this tab. It might be nice to have a "signal list"
> button to display signals associated with a widget, but maybe that's
> better dealt with via online docs.

The signal list in gazpacho is very cool because it's nice to be able
to see all the appropriate signals in one place.  The docs are good,
but it's inconvenient to have to check the entire class hierarchy.

> Maybe Gazpacho should offer a way to browse John's reference manual in a
> hypertext thingy. Or maybe I should stop giving people ideas .

An excellent idea.  Now all we have to do is contribute some code to
do it 
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-05 Thread Graham Ashton
On Thu, 2004-08-05 at 06:23, Sridhar R wrote:
> Graham Ashton <[EMAIL PROTECTED]> wrote:
> > On Wed, 2004-08-04 at 01:40, Sridhar R wrote:
> > > Graham Ashton <[EMAIL PROTECTED]> wrote:
> > >
> > > > If anybody wants a really simple implementation to this kind of wrapper
> > > > class feel free to rip off the WidgetWrapper class hierarchy that I've
> > > > knocked up here (it's tiny):
> > > >
> > > > http://cvs.sourceforge.net/viewcvs.py/bandsaw/bandsaw/src/bandsaw.py?view=markup
> > >
> > > But the signal connection part is a little bit weak.  How do you
> > > connect signals to some deeply nested widgets in that hierarchy?
> > 
> > What do you mean by deeply nested?
> 
>   child of child of .. the toplevel widget. (may be wrong terminology).

Thanks. I don't understand why you think it doesn't work.
signal_autoconnect() does the nested widgets for you. Or am I missing
the point?

-- 
Graham Ashton

___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-04 Thread Sridhar R
Graham Ashton <[EMAIL PROTECTED]> wrote:
> On Wed, 2004-08-04 at 01:40, Sridhar R wrote:
> > Graham Ashton <[EMAIL PROTECTED]> wrote:
> >
> > > If anybody wants a really simple implementation to this kind of wrapper
> > > class feel free to rip off the WidgetWrapper class hierarchy that I've
> > > knocked up here (it's tiny):
> > >
> > > http://cvs.sourceforge.net/viewcvs.py/bandsaw/bandsaw/src/bandsaw.py?view=markup
> >
> > But the signal connection part is a little bit weak.  How do you
> > connect signals to some deeply nested widgets in that hierarchy?
> 
> What do you mean by deeply nested?

  child of child of .. the toplevel widget. (may be wrong terminology).



-- 
Sridhar - http://www.cs.annauniv.edu/~rsridhar
Blog: http://www.livejournal.com/users/sridharinfinity
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-04 Thread Graham Ashton
On Wed, 2004-08-04 at 01:40, Sridhar R wrote:
> Graham Ashton <[EMAIL PROTECTED]> wrote:
> 
> > If anybody wants a really simple implementation to this kind of wrapper
> > class feel free to rip off the WidgetWrapper class hierarchy that I've
> > knocked up here (it's tiny):
> > 
> > http://cvs.sourceforge.net/viewcvs.py/bandsaw/bandsaw/src/bandsaw.py?view=markup
> 
> But the signal connection part is a little bit weak.  How do you
> connect signals to some deeply nested widgets in that hierarchy?

What do you mean by deeply nested?

-- 
Graham Ashton

___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-03 Thread Sridhar R
Graham Ashton <[EMAIL PROTECTED]> wrote:

> If anybody wants a really simple implementation to this kind of wrapper
> class feel free to rip off the WidgetWrapper class hierarchy that I've
> knocked up here (it's tiny):
> 
> http://cvs.sourceforge.net/viewcvs.py/bandsaw/bandsaw/src/bandsaw.py?view=markup

But the signal connection part is a little bit weak.  How do you
connect signals to some deeply nested widgets in that hierarchy?


-- 
Sridhar - http://www.cs.annauniv.edu/~rsridhar
Blog: http://www.livejournal.com/users/sridharinfinity
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-08-03 Thread Graham Ashton
On Wed, 2004-07-28 at 16:54, Doug Quale wrote:
> Christian Robottom Reis <[EMAIL PROTECTED]> writes:
> 
> > The issue I raised was "fear of namespace conflicts" that would be
> > introduced by this, but I think it's rather minor.
> 
> I don't actually have a strong opinion whether that change would be
> good, bad or indifferent, so I was hoping someone smarter than me
> could give some good arguments one way or the other :)

Smarter? Not me. But I have experienced it both ways. At work we've got
a rather large app (80k lines of Python), a fair chunk of which is GUI
code. We use libglade and some classes that wrap it up in a similar
manner to many of the examples posted here. The basic principle is that
your GUI class inherits from our own GWidget type thing, in which you
write lines like this:

   list_store = self._widget.treeview.get_model()

We had minor disagreement when we initially started with these classes
as to whether that was more sensible than the aesthetically cleaner:

   list_store = self._treeview.get_model()

We approached it conservatively and ended up with _widget everywhere. A
year later I can confirm that it's a right pain in the arse. I don't
know of a single situation where the _widget has protected us from a
name space collision. You could reasonably point out that I wouldn't be
likely to notice as nothing is going to go blow up in my face. Still, I
attribute the lack of evidence to support _widget to the fact that we
try and keep our classes fairly small and directed, and put business
logic and UI control code in different classes (so there's nothing more
than widgets and callbacks in the GUI code in the first place).

I recently started an open soure app of my own and decided to experiment
with a different style. In my own app I would do this:

   list_store = self.treeview.get_model()

So far I'm enjoying the extra simplicity, but then my OS app is still
less than 1k lines. My classes aren't coming out larger or smaller than
they do at work though, and that's surely a more important issue.

If anybody wants a really simple implementation to this kind of wrapper
class feel free to rip off the WidgetWrapper class hierarchy that I've
knocked up here (it's tiny):

http://cvs.sourceforge.net/viewcvs.py/bandsaw/bandsaw/src/bandsaw.py?view=markup

It's small and clean and plenty good enough for small projects. Apart
from the automatic attribute access I'm a fan of being able to write
multiple classes to manage different parts of a GUI that just happen to
have been layed out in a single glade file. Band Saw's WidgetWrapper
allows you to do this:

  class Window(WidgetWrapper):

def __init__(self):
  WidgetWrapper.__init__(self, 'window1')  # window1 is in glade
  menu = Menu(self)
  ... blah blah ...

  class Menu(WidgetWrapper):

def __init__(self, window):
  WidgetWrapper.__init__(self, 'menu1', window)

The thing to note is that the Menu is passed the window, which already
has a glade.XML object within it. The Menu just re-uses the one that the
Window has already made, saving you the overhead of loading the glade
file twice (and saving you from having two windows pop up in the event
that your top level window is visible by default). Not rocket science,
but very handy.

It's by no means as clever as the one we've got at work, but that's
proprietary and I can't rip it off. It supports clever stuff like window
stacking (i.e. transiency), object tracking (to catch memory leaks) and
other nice goodies. None of it has been that hard to do.

--
Graham

___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-28 Thread Doug Quale
Christian Robottom Reis <[EMAIL PROTECTED]> writes:

> On Wed, Jul 28, 2004 at 09:27:10AM -0500, Doug Quale wrote:
> > There are some things we can discuss whether they should be in pygtk.
> > For instance, people have considered in the past whether widget
> > properties should be attributes.  That would allow properties to be
> > get and set directly using attribute syntax in addition to using
> > get_property() and set_property().
> 
> There's actually a bug open for this that was considered for the freeze
> but eventually left out; IÃaki wrote the patch that is up at:
> 
> http://bugzilla.gnome.org/show_bug.cgi?id=81879
> 
> jpe, Johan and I have commented on it -- maybe others should chime in
> too. The issue I raised was "fear of namespace conflicts" that would be
> introduced by this, but I think it's rather minor.

I don't actually have a strong opinion whether that change would be
good, bad or indifferent, so I was hoping someone smarter than me
could give some good arguments one way or the other :)

___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-28 Thread Christian Robottom Reis
On Wed, Jul 28, 2004 at 09:27:10AM -0500, Doug Quale wrote:
> There are some things we can discuss whether they should be in pygtk.
> For instance, people have considered in the past whether widget
> properties should be attributes.  That would allow properties to be
> get and set directly using attribute syntax in addition to using
> get_property() and set_property().

There's actually a bug open for this that was considered for the freeze
but eventually left out; Iñaki wrote the patch that is up at:

http://bugzilla.gnome.org/show_bug.cgi?id=81879

jpe, Johan and I have commented on it -- maybe others should chime in
too. The issue I raised was "fear of namespace conflicts" that would be
introduced by this, but I think it's rather minor.

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 3361 2331
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-28 Thread Doug Quale
Christian Robottom Reis <[EMAIL PROTECTED]> writes:

> On Wed, Jul 28, 2004 at 12:06:38PM +0530, Sridhar R wrote:
> > we can make use of 'property' to do this ..
> > txt = button.text
> > button.text = txt

Right.  Python 2.2+ descriptors are the general mechanism upon which
'property' is built.  One of the big reasons I hacked up the widget
descriptor was that I didn't want to have to remember the correct gtk+
property to get or set for the widget value for every kind of widget.
For 98% of my GUI code I really don't care if the value I'm getting or
setting is a Label, an Entry, a SpinButton, etc.  (This is a little
lie: for labels it's nice to use pango markup so I sometimes treat
them differently than the other simple widget types.)  It's annoying
to have to remember the widget type everywhere, and if you change a
widget from an Entry to a ComboBox then you've got a bunch of fairly
pointless changes to make.

> > Another important thing is writting proxy widgets doesn't help if UI
> > is loaded from glade XML.
> 
> Why not? It shouldn't matter if the widget already exists or not -- just
> avoid building one if it already exists.

This is the importance of frameworks like kiwi.  Let the framework
manage the most tedious and/or difficult programming tasks.  If you
can get Christian to do the hard parts for you you come out ahead.

> > so putting it in a line, is this discussion all about making the pygtk
> > api much better and easy to use some which includes the one given
> > above ?
> 
> Probably not -- it's about raising good design ideas for high-level UI
> programming so I can steal them and put them in Kiwi .

Right.  I don't think most of this belongs inside of pygtk but rather
in frameworks built on pygtk.  I hope this doesn't discourage Sridar
from contributing his good ideas.  I find the discussion helpful, and
I think others reading this list do too.  For instance, I think we can
save new pygtk programmers a lot of frustration and tedium if we can
get everyone to use signal autoconnection based on method names as
Sridar and others have demonstrated instead of libglade-style
dictionary-based autoconnection.  Even so, this doesn't belong inside
pygtk itself.

There are some things we can discuss whether they should be in pygtk.
For instance, people have considered in the past whether widget
properties should be attributes.  That would allow properties to be
get and set directly using attribute syntax in addition to using
get_property() and set_property().
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-28 Thread Christian Robottom Reis
On Wed, Jul 28, 2004 at 12:06:38PM +0530, Sridhar R wrote:
> Well, writing widget classes for each GWidget class is certainly
> painful for the programmers.  All he can do concisely is to write
> lambda functions as wrappers. 

This is not the application programmer's task -- it should be
encapsulated in the framework. 

> we can make use of 'property' to do this ..
> txt = button.text
> button.text = txt
> 
> Another important thing is writting proxy widgets doesn't help if UI
> is loaded from glade XML.

Why not? It shouldn't matter if the widget already exists or not -- just
avoid building one if it already exists.

> so putting it in a line, is this discussion all about making the pygtk
> api much better and easy to use some which includes the one given
> above ?

Probably not -- it's about raising good design ideas for high-level UI
programming so I can steal them and put them in Kiwi .

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 3361 2331
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-27 Thread Sridhar R
Doug Quale <[EMAIL PROTECTED]> wrote:
> 
> There's one other possibility that I don't really understand, but I'd
> like to look into it.  PEAK is a Python framework for enterprise
> applications (http://peak.telecommunity.com/).  PEAK implements many
> fascinating ideas.  In particular its domain model module does
> something very interesting with metaclasses and nested classes.
> Applied to our area of interest it might look something like this:
> 
> class MyApp(GWidget):
> 
> class name(Widget.TextEntry):
> 
> max_length = 40
> 
> def validate(self, ...):
> # some validation code here
> 
> # other properties for the name TextEntry widget
> 
> class age(Widget.SpinButton):
> 
> step = 1
> digits = 0
> lower = 1
> upper = 120
> 
> ...
> 
> PEAK uses metaclasses to do extensive processing of the nested classes
> so that users of instances of the object see regular looking
> attributes with the same names as the nested classes.  This permits
> associating a lot of metadata with each attribute without using an
> absurd number of keyword parameters in the descriptor constructors.
> Compare this to:
> 
> class MyApp(GWidget):
> 
> def validate_name(self, ...):
> ...
> 
> name = Widget.TextEntry('name', max_length=40,
> validate_fn=validate_name,
> ...)
> 
> age = Widget.SpinButton('age', step=1, digits=0,
> lower=1, upper=120, ...)
> 
> 

Well, writing widget classes for each GWidget class is certainly
painful for the programmers.  All he can do concisely is to write
lambda functions as wrappers. But surely I'm looking for easy usage
for GTK+ widgets.

Instead of this 
txt = button.get_text()
button.set_text(txt)

we can make use of 'property' to do this ..
txt = button.text
button.text = txt

Another important thing is writting proxy widgets doesn't help if UI
is loaded from glade XML.

so putting it in a line, is this discussion all about making the pygtk
api much better and easy to use some which includes the one given
above ?

I have the implementation of StringValidator class that is used in
validation of changeable data in widgets. Look for the python module
in this snapshot
http://cs.annauniv.edu/~rsridhar/pub/pythondevelop/snapshots/
(That was a quick hack, though)

-- 
Sridhar - http://www.cs.annauniv.edu/~rsridhar
Blog: http://www.livejournal.com/users/sridharinfinity
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-27 Thread Doug Quale
Christian Robottom Reis <[EMAIL PROTECTED]> writes:

> On Sun, Jul 25, 2004 at 01:53:08PM +0530, Sridhar R wrote:
> > > def __set__(self, obj, value):
> > > widget = obj[self.widget_name]
> > > 
> > > if isinstance(widget, gtk.Label):
> > > widget.set_label(str(value))
> > > elif isinstance(widget, gtk.SpinButton):
> > > widget.set_value(value)
> > > elif isinstance(widget, gtk.Entry):
> > > widget.set_text(str(value))
> > > elif isinstance(widget, gtk.Combo):
> > > widget.get_entry().set_text(value)
> > > elif isinstance(widget, gtk.ToggleButton):
> > > widget.set_active(value)
> > > widget.set_inconsistent(value is None)
> > > elif isinstance(widget, gtk.TextView):
> > > buffer = widget.get_buffer()
> > > buffer.set_text(value)
> > > else:
> > > raise ValueError, 'Unrecognized widget type %r' % (type(widget),)
> > 
> > Introspection can be used to remove those if..else part.
> 
> Sure, you could also have a dictionary and look up an appropriate
> function to handle that widget. Maybe Doug is concerned that calling a
> function every time you want to get or set a value is going to be
> expensive?

Using a dictionary would be a better way to write this big switch and
it would be easier to maintain.  I thought when Sridar recommended
introspection that he might have meant code like:

if hasattr(widget, 'set_label'):
 widget.set_label(value)
elif hasattr(widget, 'set_value'):
widget.set_value(value)
...

This seems fine.  The alternative of doing this in try ... except
... seems too painful in this case.

The best plan is to take the suggestion you made in the other post and
create a separate descriptor class for each widget type.  That
eliminates the need for the switch entirely and provides other
benefits as you mentioned.

When writing that ugly code I didn't consider efficiency at all.  In
general in GUI code I tend not to worry too much about efficiency
unless I've tried it out and found it is too slow.  I just used the
simplest code that could possibly work, but it certainly wasn't the
best.

There's one other possibility that I don't really understand, but I'd
like to look into it.  PEAK is a Python framework for enterprise
applications (http://peak.telecommunity.com/).  PEAK implements many
fascinating ideas.  In particular its domain model module does
something very interesting with metaclasses and nested classes.
Applied to our area of interest it might look something like this:

class MyApp(GWidget):

class name(Widget.TextEntry):

max_length = 40

def validate(self, ...):
# some validation code here

# other properties for the name TextEntry widget

class age(Widget.SpinButton):

step = 1
digits = 0
lower = 1
upper = 120

...

PEAK uses metaclasses to do extensive processing of the nested classes
so that users of instances of the object see regular looking
attributes with the same names as the nested classes.  This permits
associating a lot of metadata with each attribute without using an
absurd number of keyword parameters in the descriptor constructors.
Compare this to:

class MyApp(GWidget):

def validate_name(self, ...):
...

name = Widget.TextEntry('name', max_length=40,
validate_fn=validate_name,
...)

age = Widget.SpinButton('age', step=1, digits=0,
lower=1, upper=120, ...)
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-27 Thread Doug Quale
Christian Robottom Reis <[EMAIL PROTECTED]> writes:

> On Sun, Jul 25, 2004 at 02:52:24AM -0500, Doug Quale wrote:
> This is interesting, though I question the design of that
> if-looks-like-a-switch-with-a-load-of-isinstances . 

Yes, my implementation is ugly and should be improved.  It was a quick
hack.

> Kiwi Proxies do this by creating individualized "descriptors" -- each
> widget gets its own WidgetProxy which has read() and update() methods,
> and there are WidgetProxies for every widget type [for which a
> descriptor would make sense]. This is used internally by the Kiwi Proxy,
> but could be made generally available (and even transparently available,
> as your descriptor class really is).
> 
> So in this case you could hack around them a bit and have
> 
> class MyController(GWidget):
> name = LabelProxy('name')
> age = SpinButtonProxy('name')
> 
> Maybe the StudlyCaps isn't what you're looking for (and that's the
> easiest part to change), but this solution tends to scale nicely (and
> you can add extra stuff to specific proxies, such as automatic format
> and type conversion).

That's a better idea than using the single descriptor class.  I don't
recall if I ever considered using a separate descriptor class for each
widget type.  Probably I never thought about it, but I certainly
should have.  Fortunately he amount of code I have using the ugly
implementation is small enough that I can take advantage of your good
advice and fix it.
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-27 Thread Christian Robottom Reis
On Sun, Jul 25, 2004 at 01:53:08PM +0530, Sridhar R wrote:
> > def __set__(self, obj, value):
> > widget = obj[self.widget_name]
> > 
> > if isinstance(widget, gtk.Label):
> > widget.set_label(str(value))
> > elif isinstance(widget, gtk.SpinButton):
> > widget.set_value(value)
> > elif isinstance(widget, gtk.Entry):
> > widget.set_text(str(value))
> > elif isinstance(widget, gtk.Combo):
> > widget.get_entry().set_text(value)
> > elif isinstance(widget, gtk.ToggleButton):
> > widget.set_active(value)
> > widget.set_inconsistent(value is None)
> > elif isinstance(widget, gtk.TextView):
> > buffer = widget.get_buffer()
> > buffer.set_text(value)
> > else:
> > raise ValueError, 'Unrecognized widget type %r' % (type(widget),)
> 
> Introspection can be used to remove those if..else part.

Sure, you could also have a dictionary and look up an appropriate
function to handle that widget. Maybe Doug is concerned that calling a
function every time you want to get or set a value is going to be
expensive?

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 3361 2331
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-27 Thread Christian Robottom Reis
On Sun, Jul 25, 2004 at 02:52:24AM -0500, Doug Quale wrote:
> The real reason I chose dictionary syntax over attribute syntax is
> that I use the widget names as attributes for another purpose.  The
> Python 2.2+ data descriptor facility allows using descriptors to
> provide attribute syntax to get and set widget values.
> 
> class widget(object):

[snip]

This is interesting, though I question the design of that
if-looks-like-a-switch-with-a-load-of-isinstances . 

Kiwi Proxies do this by creating individualized "descriptors" -- each
widget gets its own WidgetProxy which has read() and update() methods,
and there are WidgetProxies for every widget type [for which a
descriptor would make sense]. This is used internally by the Kiwi Proxy,
but could be made generally available (and even transparently available,
as your descriptor class really is).

> To use this, you put something like this in your class:
> 
> class MyController(GWidget):
> 
> name = widget('name')  # name entry
> age = widget('age')# age spinbutton

So in this case you could hack around them a bit and have

class MyController(GWidget):
name = LabelProxy('name')
age = SpinButtonProxy('name')

Maybe the StudlyCaps isn't what you're looking for (and that's the
easiest part to change), but this solution tends to scale nicely (and
you can add extra stuff to specific proxies, such as automatic format
and type conversion).

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 3361 2331
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-25 Thread Sridhar R
On 25 Jul 2004 11:19:27 -0500, Doug Quale <[EMAIL PROTECTED]> wrote:
> Sridhar R <[EMAIL PROTECTED]> writes:
> 
> > Doug Quale <[EMAIL PROTECTED]> wrote:
> > > Sridhar R <[EMAIL PROTECTED]> writes:
> > >
> > > About class GWidget itself, I have a few thoughts.  The __init__()
> > > method lets the caller optionally turn off autoconnection of signals.
> > > This does no harm, but are there cases in which this is useful?  I
> > > thought about this but decided that if you derive from a glade
> > > controller class you do it because you expect the on_widget__signal()
> > > methods to be connected as signal handlers.
> >
> > It will be useful if the some handlers need to be called before the
> > on_widget__signal methods.
> >
> > super(..
> > connect_my_custom_first_handlers()
> > self.autoconnect_signals()
> 
> I see, that makes sense.  I hadn't run into that situation myself.  It
> should be possible instead to override autoconnect_signals() in the
> subclass
> 
>def autoconnect_signals(self):
>connect_my_custom_first_handlers()
>super(...).autoconnect_signals()
> 
> but that certainly isn't better than using a parameter to __init__.
> It's probably worse because it requires overriding two methods instead
> of just one.
> 

One more way is to have another named method (say 'connect_handlers'),
that will be called by base's __init__ before calling
autoconnect_signals.

-- 
Sridhar - http://www.cs.annauniv.edu/~rsridhar
Blog: http://www.livejournal.com/users/sridharinfinity
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-25 Thread Doug Quale
Sridhar R <[EMAIL PROTECTED]> writes:

> Doug Quale <[EMAIL PROTECTED]> wrote:
> > Sridhar R <[EMAIL PROTECTED]> writes:
> > 
> > About class GWidget itself, I have a few thoughts.  The __init__()
> > method lets the caller optionally turn off autoconnection of signals.
> > This does no harm, but are there cases in which this is useful?  I
> > thought about this but decided that if you derive from a glade
> > controller class you do it because you expect the on_widget__signal()
> > methods to be connected as signal handlers.
> 
> It will be useful if the some handlers need to be called before the
> on_widget__signal methods.
> 
> super(..
> connect_my_custom_first_handlers()
> self.autoconnect_signals()

I see, that makes sense.  I hadn't run into that situation myself.  It
should be possible instead to override autoconnect_signals() in the
subclass

   def autoconnect_signals(self):
   connect_my_custom_first_handlers()
   super(...).autoconnect_signals()

but that certainly isn't better than using a parameter to __init__.
It's probably worse because it requires overriding two methods instead
of just one.
___
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/


Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-25 Thread Sridhar R
Doug Quale <[EMAIL PROTECTED]> wrote:
> Sridhar R <[EMAIL PROTECTED]> writes:
> 
> > I have made an utility class for making the job of using glade XML
> > file much easier.  Can this be added to pygtk?
> >
> > Main class:
> > http://cs.annauniv.edu/~rsridhar/pub/python/snippets/glade/gwidget.py
> >
> > Example (not standalone, pulled from source tree):
> > http://cs.annauniv.edu/~rsridhar/pub/python/snippets/glade/gwidget-example.py
> >
> > Thoughts?
> 
> About class GWidget itself, I have a few thoughts.  The __init__()
> method lets the caller optionally turn off autoconnection of signals.
> This does no harm, but are there cases in which this is useful?  I
> thought about this but decided that if you derive from a glade
> controller class you do it because you expect the on_widget__signal()
> methods to be connected as signal handlers.

It will be useful if the some handlers need to be called before the
on_widget__signal methods.

super(..
connect_my_custom_first_handlers()
self.autoconnect_signals()


> 
> Specifying the glade file and toplevel widget name as class attributes
> is inflexible.  It's also hard to overide in subclasses since you have
> to completely override the __init__() method if you want to specify
> the widget name dynamically.  I think the glade file and toplevel
> widget name should be parameters to __init__().

To override that create similar Class Variables in derived classes
too.  I used class variables purposedly.  For each GWidget class, the
GLADE_FILE attribute is supposed to be constant for *all* instances,
bcoz the methods are written assuming that glade file, so the glade
file can't be changed for different instances as the methods remain
the same.

> For the signal handler method names I prefer to use
> after_widget__signal() instead of on_widget__signal__().  This is just
> a matter of taste.  Using 'after_' has the disadvantage of taking
> another prefix in addition to 'on_', but it is more explicit.  One
> tiny additional advantage that we don't often think of is that the
> on/after prefixes are easier to read aloud than the silent trailing
> double underscore.

That's probably right.  Using 'after_' is more readable than suffix '__'

> 
> Making the widgets available as attributes is a good idea.  The
> Pythonic way to do this is to set the attribute when it is first
> accessed.  Subsequent accesses won't trigger __getattr__() so you
> don't need a cache:
> 
> def __getattr__(self, attr):
> new_widget = self._gladexml.get_widget(attr)
> if new_widget is None:
> raise AttributeError, 'Widget %r not found' % attr
> setattr(self, attr, new_widget)
> return new_widget
> 
> Instead of making the widgets available as attributes, I use
> __getitem__() to allow dictionary access.  This again is a matter of
> taste.  Dictionary syntax is uglier than attribute syntax but it
> avoids the chance of stepping on a name that you want to use for
> another purpose.

I feel dictionary acess is approriate.  I though self.entry1 is much
easier than self['entry']

> 
> The real reason I chose dictionary syntax over attribute syntax is
> that I use the widget names as attributes for another purpose.  The
> Python 2.2+ data descriptor facility allows using descriptors to
> provide attribute syntax to get and set widget values.
> 
> class widget(object):
> """A Python data descriptor that gets and sets values from widgets.
> 
> Use inside a class that derives from Gwidget to allow getting
> and setting widget values as attribute values.  This works
> only for widget types that have a reasonable notion of value
> like gtk.Entry, gtk.SpinButton, gtk.Combo, gtk.ToggleButton,
> gtk.Label and gtk.TextView.  Widgets that don't have an
> obvious value like gtk.TreeView are not supported.  (Generally
> tree views will be given their own controllers or
> subcontrollers.)
> """
> 
> def __init__(self, widget_name):
> self.widget_name = widget_name
> 
> def __get__(self, obj, objtype):
> widget = obj[self.widget_name]
> 
> if isinstance(widget, gtk.Label):
> return widget.get_label()
> elif isinstance(widget, gtk.SpinButton):
> return widget.get_value()
> elif isinstance(widget, gtk.Entry):
> return widget.get_text()
> elif isinstance(widget, gtk.Combo):
> return widget.get_entry().get_text()
> elif isinstance(widget, gtk.ToggleButton):
> if widget.get_inconsistent():
> return None
> else:
> return widget.get_active()
> elif isinstance(widget, gtk.TextView):
> buf = widget.get_buffer()
> start, end = buf.get_bounds()
> return buf.get_text(start, end, include_hidden_chars=True)
> else:
> raise ValueError, 'Unrecognized widget type %r' % (typ

Re: [pygtk] Glade XML wrapper and easy callbacks

2004-07-25 Thread Doug Quale
Sridhar R <[EMAIL PROTECTED]> writes:

> I have made an utility class for making the job of using glade XML
> file much easier.  Can this be added to pygtk?
> 
> Main class:
> http://cs.annauniv.edu/~rsridhar/pub/python/snippets/glade/gwidget.py
> 
> Example (not standalone, pulled from source tree):
> http://cs.annauniv.edu/~rsridhar/pub/python/snippets/glade/gwidget-example.py
> 
> Thoughts?

This is nice.  We've had good code submissions to the list recently.
I can't speak for everyone, but I appreciate seeing how others solve
problems and I learn a lot from their examples.

I use something similar to your GWidget class.  I don't know if it is
the sort of thing that belongs in pygtk itself; it seems to be better
suited for inclusion in frameworks like kiwi.  It's small enough that
it isn't too hard for users to supply it.

About class GWidget itself, I have a few thoughts.  The __init__()
method lets the caller optionally turn off autoconnection of signals.
This does no harm, but are there cases in which this is useful?  I
thought about this but decided that if you derive from a glade
controller class you do it because you expect the on_widget__signal()
methods to be connected as signal handlers.

Specifying the glade file and toplevel widget name as class attributes
is inflexible.  It's also hard to overide in subclasses since you have
to completely override the __init__() method if you want to specify
the widget name dynamically.  I think the glade file and toplevel
widget name should be parameters to __init__().

The glade controller superclass I use takes 4 parameters in __init__()
although only 2 or 3 out of the 4 are used in any individual call.
The idea is that I find it useful to create subcontrollers that share
a view (glade widgets) with their parent controllers.  These
subcontrollers don't create new widgets but just connect signals to
widgets created by the parent controller.  This can be useful in many
cases.  For example it can be used to add extra behavior to a widget,
such as autocompletion for a text entry.

def __init__(self, view_factory=None, view_name=None,
 parent=None, view=None):
"""Initializes a controller for a glade view.

The view_factory parameter is a function that returns a
glade view when given the view name.  It is used to create the
view named view_name.  Alternatively an existing view can
be passed directly using the view parameter.  This allows
creating subcontrollers that share a view with their parent.

view_factory: factory function that creates a glade view
  from the view name
view_name: name of the view to create unless view is given
parent: parent controller (optional if view_name is given)
view: gtk.glade.XML view to use for this controller
  if view_name is not given
"""

self.view = view or view_factory(view_name)
...

For the signal handler method names I prefer to use
after_widget__signal() instead of on_widget__signal__().  This is just
a matter of taste.  Using 'after_' has the disadvantage of taking
another prefix in addition to 'on_', but it is more explicit.  One
tiny additional advantage that we don't often think of is that the
on/after prefixes are easier to read aloud than the silent trailing
double underscore.

Making the widgets available as attributes is a good idea.  The
Pythonic way to do this is to set the attribute when it is first
accessed.  Subsequent accesses won't trigger __getattr__() so you
don't need a cache:

def __getattr__(self, attr):
new_widget = self._gladexml.get_widget(attr)
if new_widget is None:
raise AttributeError, 'Widget %r not found' % attr
setattr(self, attr, new_widget)
return new_widget

Instead of making the widgets available as attributes, I use
__getitem__() to allow dictionary access.  This again is a matter of
taste.  Dictionary syntax is uglier than attribute syntax but it
avoids the chance of stepping on a name that you want to use for
another purpose.

The real reason I chose dictionary syntax over attribute syntax is
that I use the widget names as attributes for another purpose.  The
Python 2.2+ data descriptor facility allows using descriptors to
provide attribute syntax to get and set widget values.

class widget(object):
"""A Python data descriptor that gets and sets values from widgets.

Use inside a class that derives from Gwidget to allow getting
and setting widget values as attribute values.  This works
only for widget types that have a reasonable notion of value
like gtk.Entry, gtk.SpinButton, gtk.Combo, gtk.ToggleButton,
gtk.Label and gtk.TextView.  Widgets that don't have an
obvious value like gtk.TreeView are not supported.  (Generally
tree views will be given their own controllers or
subcontrollers.)
"""

def