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/

Reply via email to