Search code examples
wxpythonwxwidgets

wxPython: GridBagSizer: Iterating over rows and columns of a gridbagsizer


Is there a way to iterate through the Children of a wx.GridBagSizer in row/column order?

I have noticed that I can perform a GetChildren() on a sizer but I could not find documentation in the API which says how these children actually map to rows or columns. There are two methods:

GetEffectiveRowsCount()
GetEffectiveColsCount()

But I am not sure how to use these to iterate through the children. I have included a template below:

import wx
import wx.lib.inspection


class MyRegion(wx.Frame):
    I = 0

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, title="My Region")
        gridSizer = wx.GridBagSizer()

        gridSizer.Add(self.CreateStaticBoxSizer(4), pos=(0,0), span=(4,1), flag=wx.EXPAND)
        gridSizer.Add(self.CreateStaticBoxSizer(4), pos=(4,0), span=(4,1), flag=wx.EXPAND)
        gridSizer.Add(self.CreateStaticBoxSizer(4), pos=(0,1), span=(4,1), flag=wx.EXPAND)
        gridSizer.Add(self.CreateStaticBoxSizer(8), pos=(0,2), span=(7,1), flag=wx.EXPAND)
        gridSizer.Add(self.CreateStaticBoxSizer(6), pos=(0,3), span=(6,1), flag=wx.EXPAND)

        self.SetSizer(gridSizer)
        for item in gridSizer.Children:
            for r in range(0, gridSizer.GetEffectiveRowsCount()):
                print(item.GetSize())

    def CreateStaticBoxSizer(self, x=4):
        box = wx.StaticBox(parent=self, label="StaticBox::" + str(MyRegion.I))
        MyRegion.I += 1
        sz = wx.StaticBoxSizer(orient=wx.VERTICAL, box=box)
        for i in range(x):
            sz.Add(wx.StaticText(parent=sz.GetStaticBox(),
                                 label="This window is a child of the staticbox"))
        return sz


if __name__ == "__main__":
    app = wx.App()
    frame = MyRegion(None)
    frame.Show()
    wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()

Solution

  • The items returned from GetChildren() are simply a collection of the items added to the sizer, in the order they were added. In Classic the items are wx.SizerItem objects so you can't get any information about position or spanning from them. However in Phoenix they are wx.GBSizerItem objects so you can use GetPos to find their location in the grid if desired.

    To iterate over the items in grid order you can use FindItemAtPosition which returns a wx.GBSizerItem or None if there is no item at the requested position. So something like this should give you what you are looking for:

    for row in gridSizer.GetEffectiveRowsCount():
        for col in gridSizer.GetEffectiveColsCount():
            item = gridSizer.FindItemAtPosition((row, col))
            if item is not None:
                print(item.GetSize())