[...]
>       I use the class so that I can have a common namespace, but importing __main__ 
>every time I want to access it seems not only ugly, but "wrong" due to the lack
> of modularity. Is there a better way I can write/structure this program's namespace?
[...]

This is the code I wrote to solve this for SQmaiL:

---snip---
class WidgetStore:
        def __init__(self, tree):
                self._tree = tree

        def __getattr__(self, attr):
                w = self._tree.get_widget(attr)
                if not w:
                        raise AttributeError("Widget "+attr+" not found")
                self.__dict__[attr] = w
                return w
        __getitem__ = __getattr__
        
class _callback:
        def __init__(self, dest, method):
                self.dest = dest
                self.method = method
        
        def __call__(self, *args):
                try:
                        return apply(self.method, (self.dest,) + args)
                except TypeError:
                        print "Exception while calling", self.method.__name__, "on", 
self.dest
                        print "Args:", args
                        raise

class Callback:
        def __init__(self, dest):
                self.dest = dest
                self.dict = {}
                for i in self.dest.__class__.__bases__:
                        self.dict.update(i.__dict__)
                self.dict.update(self.dest.__class__.__dict__)

        def items(self):
                l = []
                for key, value in self.dest.__class__.__dict__.items():
                        if (type(value) == types.FunctionType):
                                l.append((key, _callback(self.dest, value)))
                return l
        
        def __getitem__(self, name):
                return _callback(self.dest, self.dict[name])
---snip---

WidgetStore is an interface to a Glade tree; Callback is a wrapper to allow you
to send callbacks to a specific object.

I use it like this:

---snip---
class SQmaiLReader:
        gladefilename = "sqmail.glade"

        def __init__(self):
                [...]
                # Create the main window and the widget store.

                self.mainwindow = self.readglade("mainwin")
                self.widget = sqmail.gui.utils.WidgetStore(self.mainwindow)     
                [...]
                gtk.mainloop()

        # Read in a Glade tree. Signals are attached to methods on the
        # supplied object o; if o is omitted, this object is used.
        
        def readglade(self, name, o=None):
                if not o:
                        o = self
                obj = libglade.GladeXML(self.gladefilename, name)
                obj.signal_autoconnect(sqmail.gui.utils.Callback(o))
                return obj
---snip---

Now I can do "self.widget.glade_widget_name" and it will automatically look up
"glade_widget_name" in the tree and return it to me (all cached so it's fast).
What's more, I can tell Glade to connect a button to the signal
"on_quit" and when I press it, the "on_quit()" method is
automatically invoked:

---snip---
        def on_quit(self, obj):
                sys.exit(0)
---snip---

Very, very handy. It could hardly make development with Glade and Python easier.
Python is a Good Thing.

-- 
+- David Given ---------------McQ-+ 
|  Work: [EMAIL PROTECTED]         | "Ignore reality. There's nothing you can
|  Play: [EMAIL PROTECTED]         | do about it." --- Natalie Imbruglia        
+- http://wired.st-and.ac.uk/~dg -+ 


_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk

Reply via email to