wxPython: Switching between multiple panels with a button
Question: I would like to have two (I will add more later) panels that occupy the same
space within the frame and for them to be shown/hidden when the respective
button is pressed on the toolbar, "mListPanel" should be the default.
Currently the settings panel is shown when the application is launched and the
buttons don't do anything. I've searched and tried lots of stuff for hours and
still can't get it to work. I apologise if it's something simple, I've only
started learning python today.

This is what the code looks like now:

    
    
        import wx
    
        class mListPanel(wx.Panel):
            def __init__(self, parent):
                wx.Panel.__init__(self, parent=parent)
                    #wx.StaticText(self, -1, label='Search:')#, pos=(10, 3))
                    #wx.TextCtrl(self, pos=(10, 10), size=(250, 50))
    
        class settingsPanel(wx.Panel):
            def __init__(self, parent):
                wx.Panel.__init__(self, parent=parent)
    
        class bifr(wx.Frame):
            def __init__(self):
                wx.Frame.__init__(self, None, wx.ID_ANY, "Title")
    
                self.listPanel = mListPanel(self)
                self.optPanel = settingsPanel(self)
    
                menuBar = wx.MenuBar()
                fileButton = wx.Menu()
                importItem = wx.Menu()
                fileButton.AppendMenu(wx.ID_ADD, 'Add M', importItem)
                importItem.Append(wx.ID_ANY, 'Import from computer')
                importItem.Append(wx.ID_ANY, 'Import from the internet')
                exitItem = fileButton.Append(wx.ID_EXIT, 'Exit')
                menuBar.Append(fileButton, 'File')
                self.SetMenuBar(menuBar)
                self.Bind(wx.EVT_MENU, self.Quit, exitItem)
    
                toolBar = self.CreateToolBar()
                homeToolButton = toolBar.AddLabelTool(wx.ID_ANY, 'Home', wx.Bitmap('icons/home_icon&32.png'))
                importLocalToolButton = toolBar.AddLabelTool(wx.ID_ANY, 'Import from computer', wx.Bitmap('icons/comp_icon&32.png'))
                importToolButton = toolBar.AddLabelTool(wx.ID_ANY, 'Import from the internet', wx.Bitmap('icons/arrow_bottom_icon&32.png'))
                settingsToolButton = toolBar.AddLabelTool(wx.ID_ANY, 'settings', wx.Bitmap('icons/wrench_plus_2_icon&32.png'))
                toolBar.Realize()
    
                self.Bind(wx.EVT_TOOL, self.switchPanels(), settingsToolButton)
                self.Bind(wx.EVT_TOOL, self.switchPanels(), homeToolButton)
                self.Layout()
    
            def switchPanels(self):
                if self.optPanel.IsShown():
                    self.optPanel.Hide()
                    self.listPanel.Show()
                    self.SetTitle("Home")
                elif self.listPanel.IsShown():
                    self.listPanel.Hide()
                    self.optPanel.Show()
                    self.SetTitle("Settings")
                else:
                    self.SetTitle("Error")
                self.Layout()
    
            def Quit(self, e):
                self.Close()
    
        if __name__ == "__main__":
            app = wx.App(False)
            frame = bifr()
            frame.Show()
            app.MainLoop()
    


Answer: first off, i would highly suggest that you learn about [wxpython
sizers](http://wiki.wxpython.org/UsingSizers) and get a good understanding of
them (they're really not that hard the understand) as soon as possible before
delving deeper into wxpython, just a friendly tip :).

as for your example, a few things: when your'e not using sizers, you have to
give size and position for every window or else they just wont show, so you'd
have to change your panel classes to something like this (again this is only
for demonstration, you should be doing this with wx.sizers, and not position
and size):

    
    
    class mListPanel(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent=parent,pos=(0,100),size=(500,500))
    
    class settingsPanel(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent=parent,pos=(0,200),size (1000,1000))
    

further more, when binding an event it should look like this:

    
    
    self.Bind(wx.EVT_TOOL, self.switchPanels, settingsToolButton)
    self.Bind(wx.EVT_TOOL, self.switchPanels, homeToolButton)
    

notice how I've written only the name of the function without the added (), as
an event is passed to it, you cant enter your own parameters to a function
emitted from an event (unless you do it with the following syntax lambda
e:FooEventHandler(paramaters))

and the event handler (function) should look like this:

    
    
    def switchPanels(self, event):
        if self.optPanel.IsShown():
            self.optPanel.Hide()
            self.listPanel.Show()
            self.SetTitle("Home")
        elif self.listPanel.IsShown():
            self.listPanel.Hide()
            self.optPanel.Show()
            self.SetTitle("Settings")
        else:
            self.SetTitle("Error")
        self.Layout()
    

there should always be a second parameter next to self in functions that are
bind to event as the event object is passes there, and you can find its
associated methods and parameters in the documentation (in this example it is
the wx.EVT_TOOL).

