wxPython: How to Get Children Widgets from a Sizer

Posted by Mike on August 24th, 2012 filed in Python, Python GUI Toolkits, wxPython

The other day, I stumbled across a question on StackOverflow asking how to get the children widgets of a BoxSizer. In wxPython, you would expect to call the sizer’s GetChildren() method. However, this returns a list of SizerItems objects rather than a list of the actual widgets themselves. You can see the difference if you call a wx.Panel’s GetChildren() method. Now I don’t ask a lot of questions on the wxPython users group list, but I was curious about this one and ended up receiving a quick answer from Cody Precord, author of the wxPython Cookbook and Editra. Anyway, he ended up pointing me in the right direction and I came up with the following bit of code:

import wx
 
########################################################################
class MyApp(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Example")
        panel = wx.Panel(self)
 
        lbl = wx.StaticText(panel, label="I'm a label!")
        txt = wx.TextCtrl(panel, value="blah blah")
        btn = wx.Button(panel, label="Clear")
        btn.Bind(wx.EVT_BUTTON, self.onClear)
 
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(lbl, 0, wx.ALL, 5)
        self.sizer.Add(txt, 0, wx.ALL, 5)
        self.sizer.Add(btn, 0, wx.ALL, 5)
 
        panel.SetSizer(self.sizer)
 
    #----------------------------------------------------------------------
    def onClear(self, event):
        """"""
        children = self.sizer.GetChildren()
 
        for child in children:
            widget = child.GetWindow()
            print widget
            if isinstance(widget, wx.TextCtrl):
                widget.Clear()
 
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyApp()
    frame.Show()
    app.MainLoop()

The important bit is in the onClear method. Here we need to call the SizerItem’s GetWindow() method to return the actual widget instance. Once we have that, we can do stuff with the widget, such as change the label, value or in this case, clear the text control. Now you know how to get access to a sizer’s children widgets too.

Print Friendly

  • dncarac

    Off topic, but I see Cory used the old-fashioned method of calling the __init__ method of the wx.Frame class. I’ve tried to use the newfangled method of calling super. But I really have no idea of why.

    Could you look into this and explain the whys and wherefores of using he old-fashioned versus the newfangled methods?

    Thanks