wxpython boxsizer:problems with dynamically adding items
This is driving me nuts. I usually use Tkinter for gui stuff, but just felt like actually trying to learn wxpython.
I can't for the life of me figure out why when I add items like buttons or static text to a panel, using a boxsizer. It just seems to cram everything into position (0,0) on the panel called "side" heres my code.
import wx def AddUser(): ex = wx.App() Stylex = wx.SYSTEM_MENU|wx.CAPTION|wx.CLOSE_BOX window = wx.Frame(None, style=Stylex) splitter = wx.SplitterWindow(window, -1) vbox = wx.BoxSizer(wx.VERTICAL) """ LEFT PANEL... Contains Navigation Tree """ fgs = wx.FlexGridSizer(2,1,5,10) # fgs(int rows, int cols, int vgap, int hgap panel = wx.Panel(splitter, -1) panel.SetBackgroundColour('#ededed') side = wx.Panel(splitter, -1) side.SetBackgroundColour('#4f5049') multi_btn = wx.Button(panel, label="Batch User Mode") multi_btn.SetId(50) single_btn = wx.Button(panel, label="Single User Mode") single_btn.SetId(25) items = [multi_btn,single_btn] fgs.AddMany(items) vbox.Add(fgs) panel.SetSizer(vbox) splitter.SplitVertically(panel, side,100) """ SIDE panel... Contains all widgets """ st = wx.StaticText(side, label="Select a Mode", pos=wx.Point(20,100)) st.SetForegroundColour(wx.WHITE) def SetMode(event): """ 25 returned if Single user mode 50 returned if Batch user mode """ MODE = event.GetId() if MODE == 25: try: side.DestroyChildren() except: pass """ Problem adding items to the dynamnic changing 'SIDE' panel """ vb = wx.BoxSizer(wx.VERTICAL) stFName = wx.StaticText(side, id=2,label="First Name:") stFName.SetForegroundColour(wx.WHITE) vb.Add(stFName) tcFName = wx.TextCtrl(side, id=4) vb.Add(tcFName) stLName = wx.StaticText(side,id=6, label="Last Name:") vb.Add(stLName) tcLName = wx.TextCtrl(side, id=8) vb.Add(tcLName) vb.Add(side, 1, flag=wx.EXPAND|wx.ALL, border=5) side.SetSizer(vb) """ END Problem """ if MODE == 50: try: side.DestroyChildren() except: pass """ do the same thing as single user creation, except adding listboxes instead of textctrl's """ return multi_btn.Bind(wx.EVT_BUTTON, SetMode) single_btn.Bind(wx.EVT_BUTTON, SetMode) window.SetTitle('User Creation Process') window.Centre() window.Show(True) ex.MainLoop() if __name__=='__main__': AddUser()
Thanks very much for any help... I'm sure its something small that I overlooked, but I would like to understand if its a fundamental problem.
That's the default placement. Sizers are NOT for absolute positioning. If you want to, you can do that by passing a position in each widget. If you want your widgets centered on the left, then you'll need to but the vertical BoxSizer inside of a horizontal one and center it. Or you can use a couple of Spacers by using AddSpacer or by just adding a size:
mySizer.Add((10, 20), 0, wx.ALL, 5)
You can also use the "border" parameter of the Sizer's Add method to control placement to some degree using wx.TOP, wx.BOTTOM, wx.RIGHT or wx.LEFT and giving it the appropriate amount of space. If you are seeing the widgets getting stacked, then you'll need to add a Layout call at the end (probably from the panel or the frame).
UPDATE: If you want to swap out panels, I would recommend just hiding and showing them or destroying and creating panels. I wrote up a tutorial on switching panels that might help: http://www.blog.pythonlibrary.org/2010/06/16/wxpython-how-to-switch-between-panels/