Dave Reed <[EMAIL PROTECTED]> writes: > There have been a number of questions on this list about using > Glade/pygtk together. I have written some software that produces a > skeleton of your program's code with empty callbacks/signal handlers > based on the contents of the glade XML file.
Thanks for making your code available. It would be interesting to hear how others in this group organize their pygtk and Glade code. I don't know if anyone else will care to share their ideas. I have a few thoughts about connecting signal handlers using libglade and pygtk -- I hope it isn't too dry and boring. There are at least 3 ways to connect signal handlers to pygtk libglade widgets: code generation, libglade autoconnect and introspection. Code generation has advantages, but also a few disadvantages too. I think the biggest practical problem is that it can be hard to keep the code in sync with changes to the Glade file. First, you have to remember to regenerate the skeleton when you change the Glade file. That's not too bad, but a bigger problem is that it can be hard to merge the code you used to fill out an old skeleton into a newly generated skeleton. In order to avoid overwriting too much hand-written code and to make merging easier, it is sometimes suggested to divide the interface into several small Glade files so that each generated skeleton is smaller. Code generation of skeletons can make it easier to get started but I think it makes updates significantly harder. I prefer code generation techniques when they can create complete functions or classes rather than skeletons so that the update problem is minimized. (If changes to the generated code are rare then skeletons can be fine but this isn't my experience with what happens with typical GUI view and controller code.) Questions about libglade autoconnect come up on this list fairly regularly. Autoconnect is probably a good approach for libglade projects in C, but I'm not a fan of using it with pygtk. Glade should be used to build the view. Signal handlers are part of the controller so I don't think they belong in the Glade file. Glade needs the signal and handler names to direct its code generation, but with libglade we can make a cleaner separation between view and controller so we shouldn't have to specify the signal handlers in two places. One thing I do like about the Glade signal dialog is that it does a good job of showing the signals that are available for each widget. Introspection allows you to specify the signal handlers in a natural way in your pygtk code and have them connected automatically. This is one of several ideas that Christian Reis uses to great effect in Kiwi. Controller classes automatically connect signals based on method names that match patterns like on_widget__signal and after_widget__signal. There is no need to specify the signal handlers in Glade since this information is not used. To connect to another widget or signal you just write a new method with the appropriate name and no changes are needed to the Glade file. Of course this constrains signal handler method names to fit the chosen patterns, but I think this is a good coding practice anyway. This is the approach I like best. The pygtk FAQ entry 22.1 talks about connecting signals when using libglade. It includes some links and some example code. One example given uses introspection + autoconnect. I don't understand this choice since it needlessly brings with it all the disadvantages of libglade autoconnect. Instead, something like this seems better since all signal handling stuff remains in the Python code and there is no need to set signals and handler names in the Glade file: import re # Regular expression to match handler method names patterns # on_widget__signal and after_widget__signal. Note that we use two # underscores between the Glade widget name and the signal name. handler_re = re.compile(r'^(on|after)_(.*)__(.*)$') class GladeWidget: def init(self, glade_file, widget_name): """Connects signal handling methods to Glade widgets. Methods named like on_widget__signal or after_widget__signal are connected to the appropriate widgets and signals. """ get_widget = gtk.glade.XML(glade_file, widget_name).get_widget for attr in dir(self): match = handler_re.match(attr) if match: when, widget, signal = match.groups() method = getattr(self, attr) assert callable(method) if when == 'on': get_widget(widget).connect(signal, method) elif when == 'after': get_widget(widget).connect_after(signal, method) elif attr.startswith('on_') or attr.startswith('after_'): # Warn about some possible typos like separating # widget and signal name with _ instead of __. print ('Warning: attribute %r not connected' ' as a signal handler' % (attr,)) _______________________________________________ pygtk mailing list [EMAIL PROTECTED] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/