Every couple of months, I’ll see someone asking how to switch between two views or panels in a wxPython application that they’re working on. Since this is such a common question and because I had it asked last week on the wxPython channel on IRC, I wrote up a quick script that shows how it’s done. Note that in most cases, the user will probably find one of the many notebook widgets to be more than sufficient for their needs. Anyway, let’s take a look at how to do this thing!

In this example, we’ll use a menu to toggle between two panels. The first panel will have just a text control on it and the second panel will just have a grid widget.

import wx
import wx.grid as gridlib
 
########################################################################
class PanelOne(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)
        txt = wx.TextCtrl(self)
 
########################################################################
class PanelTwo(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)
 
        grid = gridlib.Grid(self)
        grid.CreateGrid(25,12)
 
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(grid, 0, wx.EXPAND)
        self.SetSizer(sizer)
 
########################################################################
class MyForm(wx.Frame):
 
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "Panel Switcher Tutorial")
 
        self.panel_one = PanelOne(self)
        self.panel_two = PanelTwo(self)
        self.panel_two.Hide()
 
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.panel_one, 1, wx.EXPAND)
        self.sizer.Add(self.panel_two, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
 
 
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        switch_panels_menu_item = fileMenu.Append(wx.ID_ANY, 
                                                  "Switch Panels", 
                                                  "Some text")
        self.Bind(wx.EVT_MENU, self.onSwitchPanels, 
                  switch_panels_menu_item)
        menubar.Append(fileMenu, '&File')
        self.SetMenuBar(menubar)
 
    #----------------------------------------------------------------------
    def onSwitchPanels(self, event):
        """"""
        if self.panel_one.IsShown():
            self.SetTitle("Panel Two Showing")
            self.panel_one.Hide()
            self.panel_two.Show()
        else:
            self.SetTitle("Panel One Showing")
            self.panel_one.Show()
            self.panel_two.Hide()
        self.Layout()
 
 
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()

The only code that we care about is located in the onSwitchPanels event handler. Here we use a conditional to check which panel is showing and then Hide the current one and Show the other. We also set the frame’s title to make it obvious which panel is which. We also need to call the frame’s Layout() method to make the panels visible. Otherwise you might see some weird visual anomalies like nothing really showing in the frame unless you resize it slightly.

Now you know how to switch panels too. If you plan to do a lot of visual work, like adding or deleting widgets, then you might want to look into the Freeze and Thaw methods and then use Layout. They help hide the flickering that can be seen when you modify a panel’s children.

Print Friendly