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.