Search code examples
wxpythonwxwidgets

wx.GridBagSizer + wx.StaticBoxSizer: How to automate span calculation


I have the following following window generated by using a function called CreateStaticBoxSizer however StaticBox3 contains empty spaces at the end of it which I dont want it to.

I would like it to contain no empty space. I noticed that if I put the span for StaticBox3 to be 7 it gives the result which I want but would like to automate the process of generating a span as opposed to hard-coding it:

BoxSizer containing space

The code uses a span based on the number of items it creates, so if it creates 8 items within the boxSizer, it uses a span of 8.

I can't understand why this is wrong can someone please clarify? What should the span be corresponding to?

Also as StaticBox::4 is intruding on the row of StaticBox::1 why doesn't it expand like StaticBox::3 does?

The code to generate this is as follows:

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=(8,1), flag=wx.EXPAND)
        gridSizer.Add(self.CreateStaticBoxSizer(6), pos=(0,3), span=(6,1), flag=wx.EXPAND)

        self.SetSizer(gridSizer)

    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

  • Your sizer #3 has a row span of 8, so it has the same height of as the sum of the sizers #0 and #1, and this is what results in the gap as the two sizers have 2 labels which take more vertical space than one.

    There are probably ways to make it work wxGridBagSizer but IMO this sizer should (almost) never be used anyhow. For any kind of normal layout you should use wxFlexGridSizer and wxBoxSizer instead.