Recursively walking all a widget’s descendants in PyGTK

The other day, I had a need to walk through all the descendants of a dialog box in PyGTK, so that I could save the contents of each text-entry field to the appropriate database record. After a bit of poking around in the PyGTK manual and not finding the recursive get_children() function that I wanted, I decided to write my own.

def walk_descendants(root):
    """
    Walk through a tree of this object's children, their own children,
    and so on, yielding each object in depth-first order.
    """
    yield root
    if not hasattr(root, 'get_children'):
        return # No children, so we're done
    children = root.get_children()
    if not children:
        return # No children, so we're done
    for child in children:
        for widget in walk_descendants(child):
            yield widget

I use this function to build a dict listing all the widgets in my dialog box, keyed by their names. Then when I need to do something with the OK button, I can use something like self.widgets['button_OK'] and no matter where it is in the hierarchy, even nested inside several VBoxes and HBoxes, it’s easy to use.

In case others might find this useful, I hereby release this function into the public domain. Use it however you like.

2 Comments

  • Tim Peterson says:

    I happened across your site via Google, and, being a Christian geek myself, decided to poke around. However, I was disturbed to find some nasty spam links lurking at the bottom of several posts and the wishlist page — looks like somebody hacked you. I don’t see any direct means of contacting you, so I had to do it this way instead.

  • Robin Munn says:

    Thanks for the note. It’s been way too long since I updated my site, so I only just saw your comment now. I’ve just gone through and cleaned out the spam. I also upgraded to the latest version of WordPress, so hopefully whatever security hole they used to hack me will be closed now.

Leave a Reply

XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Warning: include_once(/home/rmunn/geekforgod.com/wp-content/plugins/SK2/sk2_plugins/f14b3.php) [function.include-once]: failed to open stream: Permission denied in /home/rmunn/geekforgod.com/wp-content/plugins/SK2/sk2_core_class.php on line 66

Warning: include_once() [function.include]: Failed opening '/home/rmunn/geekforgod.com/wp-content/plugins/SK2/sk2_plugins/f14b3.php' for inclusion (include_path='.:/usr/local/lib/php:/usr/local/php5/lib/pear') in /home/rmunn/geekforgod.com/wp-content/plugins/SK2/sk2_core_class.php on line 66

Fatal error: Cannot redeclare remove_accents() (previously declared in /home/rmunn/geekforgod.com/wp-includes/formatting.php:532) in /home/rmunn/geekforgod.com/wp-content/plugins/SK2/sk2_plugins/b3343.php on line 105