wx.GridSizer: Problem with setting borders

I’m having a problem with wx.Gridsizer. The posted code creates a nested series of controls. The puzzle is a 3x3 grid of panes where each pane is a 3x3 grid of tiles and each tile is a 3x3 grid of buttons. I want to set the parameters for the outer two gridsizers so that each pane and each tile is evenly separated from the other panes and tiles. As such, I created the two lists, RPAD and CPAD (indexed by 0-relative row and column numbers). If you run the code and compare the displayed GUI and the printed output you’ll see that they seem to be at odds. You’ll see that there is a wider border between rows 1 & 2, and columns 1 and 2. Take panes 1 & 2. The given values are

Pane(1) padding is wx.TOP
Pane(2) padding is wx.TOP wx.RIGHT

The GUI, however, has extra padding added either to the right of pane 1 or the left of pane 2. If I am misinterpreting the use of borders and padding could you please explain what I am doing incorrectly?

import wx
import wx.lib.mixins.inspection

RPAD = (wx.TOP , 0, wx.BOTTOM)
rpad = ('wx.TOP ', '', 'wx.BOTTOM ')

CPAD = (wx.LEFT, 0, wx.RIGHT)
cpad = ('wx.LEFT ', '', 'wx.RIGHT ')

PANEBORDER = 20
TILEBORDER =  5      


class App(wx.App):

    def OnInit(self):

        self.frame = Frame()
        self.frame.Position = (10,10)
        self.frame.Show()
        return True


class Frame(wx.Frame):

    def __init__(self):

        wx.Frame.__init__(self, None, title="Sudoku", style=wx.CLOSE_BOX | wx.CAPTION)

        self.SetBackgroundColour('white')

        self.puzzle = Puzzle(self)
        bsizer = wx.BoxSizer(wx.HORIZONTAL)
        bsizer.Add(self.puzzle,0,wx.ALL,10)
        self.SetSizerAndFit(bsizer)


class Puzzle(wx.Panel):

    def __init__(self, parent):

        wx.Panel.__init__(self, parent, -1, style=wx.BORDER_DOUBLE)
        self.SetBackgroundColour('light grey')  

        gsizer = wx.GridSizer(cols=3, vgap=5, hgap=5)

        for row in (0,1,2):
            print("")
            for col in (0,1,2):
                print("Pane(%d) padding is %s%s" % (3*row+col,rpad[row], cpad[col]))
                pane = Pane(self)
                gsizer.Add(pane,0,RPAD[row] | CPAD[col], border=PANEBORDER)

        self.SetSizerAndFit(gsizer)

class Pane(wx.Panel):

    def __init__(self, parent):

        wx.Panel.__init__(self, parent, -1, style=wx.BORDER_DOUBLE)

        self.SetBackgroundColour('yellow')  

        gsizer = wx.GridSizer(cols=3, vgap=5, hgap=5)

        for row in (0,1,2):
            print("")
            for col in (0,1,2):
                print("  Tile(%d) padding is %s%s" % (3*row+col,rpad[row], cpad[col]))
                tile = Tile(self)
                gsizer.Add(tile,0,RPAD[row] | CPAD[col], border=TILEBORDER)
        print("")

        self.SetSizerAndFit(gsizer)


class Tile(wx.Panel):

    def __init__(self, parent):

        wx.Panel.__init__(self, parent, -1, style=wx.BORDER_DOUBLE)

        gsizer = wx.GridSizer(cols=3, vgap=0, hgap=0) 

        for i in range(1,10): 
            button = wx.Button(self,label = str(i), size=(24,24))
            gsizer.Add(button,0,0,0)      

        self.SetSizerAndFit(gsizer)  

if __name__ == '__main__':
    app = App(False) 
    wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()

I’m not entirely certain why this did it but I added wx.ALIGN_CENTRE to the flags.

I tend to avoid SetSizerAndFit as it has some unexpected side-effects. Usually just a SetSizer everywhere, and a self.Fit() on the frame is sufficient.

Also for grid sizers, in most cases I tend to not try to deal with internal borders and flags. I just set the hgap and vgap to good values. If I want more space around the edge then I put the grid sizer in a BoxSizer and set the outer margin size there.

That’s good to know. I finished my learning project (the Sudoku tool) that was the subject of my previous thread. I wrote up the entire development as a rather length tutorial and posted it on Daniweb. Thanks for the feedback.