Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wxPython - picking the right sizer to use in an application

Tags:

wxpython

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...
like image 624
Enrico Tuvera Jr Avatar asked Feb 27 '23 22:02

Enrico Tuvera Jr


1 Answers

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

like image 111
Curt Avatar answered Mar 03 '23 20:03

Curt