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.