wxPython - picking the right sizer to use in an application
Question: I'm having trouble figuring out how to get the sizers in wxPython to work the
way I want them to (aside: am I the only one who thinks that wxPython is
poorly documented?). I've got 4 buttons and a textctrl that I want arranged
like so:

    
    
    ==============================================
    |WINDOW TITLE                          _ [] X|
    |============================================|
    |Button1  |  Button2  |   Button3  |  Button4|
    |--------------------------------------------|
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
    |xxxxxxxxxxxxxxxxxxTextCtrlxxxxxxxxxxxxxxxxxx|
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
    |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
    ==============================================
    

The buttons should expand horizontally, but not vertically, and the textctrl
should expand both horizontally and vertically. I've tried pretty much every
sizer listed in the wxPython demo program and none of them worked - multiple
boxsizers, gridsizers + boxsizeres, plain gridsizer, flexgridsizer and
rowcolsizer but none of it works, could someone help? For reference, here's
the code that I've got right now.

    
    
                ...snip...
                panel = wx.Panel(self, -1)
                select_file = wx.Button(panel, self.BUTTON_0, "Select File")
                button1 = wx.Button(panel, self.BUTTON_1, "250 Words") 
                button2 = wx.Button(panel, self.BUTTON_2, "500 Words") 
                button3 = wx.Button(panel, self.BUTTON_3, "750 Words") 
                self.txt = wx.TextCtrl(panel, -1, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
    
                # Now to re-do this with gridsizers instead.
                # 4 rows, 4 columns, 2 pixel gap horizontally and vertically.
                grid = rcs.RowColSizer()
    
                # These buttons need to expand to fill their space, and then
                # expand when the windows are resized.
                grid.Add( select_file, row=1, col=1 )
                grid.Add( button1, row=1, col=2 )
                grid.Add( button2, row=1, col=3 )
                grid.Add( button3, row=1, col=4 )
                grid.Add( self.txt, row=2, col=1 )
                ...snip...
    


Answer: It took me a while to figure this out. It's something that I do with wxPython
all the time. Essentially you need to nest box sizers. You need one vertical
box sizer that holds two horizontal box sizers.

Here is the code you need:

    
    
    import wx
    
    class sizertest(wx.Panel):
    
        def __init__(self,parent):
            wx.Panel.__init__(self,parent)
            vsizer = wx.BoxSizer(wx.VERTICAL)
            hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
    
            button1 = wx.Button(self,-1,"button 1")
            self.Bind( wx.EVT_BUTTON,self.button1,button1)
            hsizer1.Add(button1,1,wx.EXPAND)
    
            button2 = wx.Button(self,-1,"button 2")
            self.Bind( wx.EVT_BUTTON,self.button2,button2)
            hsizer1.Add(button2,1,wx.EXPAND)
    
            vsizer.Add(hsizer1,.1,wx.EXPAND)
            self.SetSizer(vsizer)
    
            tc = wx.TextCtrl(self,-1,"",style=wx.TE_MULTILINE)
            hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
            hsizer2.Add(tc,1,wx.EXPAND)
            vsizer.Add(hsizer2,1,wx.EXPAND)
    
        def button1(self,event):pass
        def button2(self,event):pass
    
    
    if __name__ == "__main__":
        app = wx.App()
        frame = wx.Frame(parent=None, id=-1, title="sizer test")
        panel = sizertest(frame)
    
        frame.Show()
        app.MainLoop()
    

The vertical sizer vsizer holds two horizontal sizers. The first horizontal
sizer holds as many buttons as you want to add to it, and they can expand
horizontally. Because you add it to the vertical sizer with a number less than
one for its "weight" it will not expand vertically. The second horizontal
sizer holds the text control, and it can expand to take up all the remaining
horizontal and vertical space. Both sizers expand as the window is expanded.

I recommend that you get the book wxPython in Action by Rappin and Dunn - it
really helped me understand how the wxPython sizers and screen layout works.

I use nested boxsizers for 99% of my wxPython programs.

Curt

