Learning wxPython by Example.


A Full Example

The following code shows an example of a wxPython application with a frame containing a menu bar, status bar and panel. The panel contains a label and a button that is bound to an exit function. The menu bar has a Help->About action that is bound to a dialog box. The dialog box shows how to display an HTML message and bring up a link in the user's default browser. You might find this example useful as a starting point that you can adapt. In a larger program it would be best to put the about box code into a separate file so that the main program file does not become too large. If this example is too large to start with then see the second example.

   1 #!/usr/bin/python
   2 # -*- coding: <<encoding>> -*-
   3 #-------------------------------------------------------------------------------
   4 #   <<project>>
   5 # 
   6 #-------------------------------------------------------------------------------
   8 import wxversion
   9 wxversion.select("2.8")
  10 import wx, wx.html
  11 import sys
  13 aboutText = """<p>Sorry, there is no information about this program. It is
  14 running on version %(wxpy)s of <b>wxPython</b> and %(python)s of <b>Python</b>.
  15 See <a href="http://wiki.wxpython.org">wxPython Wiki</a></p>""" 
  17 class HtmlWindow(wx.html.HtmlWindow):
  18     def __init__(self, parent, id, size=(600,400)):
  19         wx.html.HtmlWindow.__init__(self,parent, id, size=size)
  20         if "gtk2" in wx.PlatformInfo:
  21             self.SetStandardFonts()
  23     def OnLinkClicked(self, link):
  24         wx.LaunchDefaultBrowser(link.GetHref())
  26 class AboutBox(wx.Dialog):
  27     def __init__(self):
  28         wx.Dialog.__init__(self, None, -1, "About <<project>>",
  30                 wx.TAB_TRAVERSAL)
  31         hwin = HtmlWindow(self, -1, size=(400,200))
  32         vers = {}
  33         vers["python"] = sys.version.split()[0]
  34         vers["wxpy"] = wx.VERSION_STRING
  35         hwin.SetPage(aboutText % vers)
  36         btn = hwin.FindWindowById(wx.ID_OK)
  37         irep = hwin.GetInternalRepresentation()
  38         hwin.SetSize((irep.GetWidth()+25, irep.GetHeight()+10))
  39         self.SetClientSize(hwin.GetSize())
  40         self.CentreOnParent(wx.BOTH)
  41         self.SetFocus()
  43 class Frame(wx.Frame):
  44     def __init__(self, title):
  45         wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(350,200))
  46         self.Bind(wx.EVT_CLOSE, self.OnClose)
  48         menuBar = wx.MenuBar()
  49         menu = wx.Menu()
  50         m_exit = menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Close window and exit program.")
  51         self.Bind(wx.EVT_MENU, self.OnClose, m_exit)
  52         menuBar.Append(menu, "&File")
  53         menu = wx.Menu()
  54         m_about = menu.Append(wx.ID_ABOUT, "&About", "Information about this program")
  55         self.Bind(wx.EVT_MENU, self.OnAbout, m_about)
  56         menuBar.Append(menu, "&Help")
  57         self.SetMenuBar(menuBar)
  59         self.statusbar = self.CreateStatusBar()
  61         panel = wx.Panel(self)
  62         box = wx.BoxSizer(wx.VERTICAL)
  64         m_text = wx.StaticText(panel, -1, "Hello World!")
  65         m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
  66         m_text.SetSize(m_text.GetBestSize())
  67         box.Add(m_text, 0, wx.ALL, 10)
  69         m_close = wx.Button(panel, wx.ID_CLOSE, "Close")
  70         m_close.Bind(wx.EVT_BUTTON, self.OnClose)
  71         box.Add(m_close, 0, wx.ALL, 10)
  73         panel.SetSizer(box)
  74         panel.Layout()
  76     def OnClose(self, event):
  77         dlg = wx.MessageDialog(self, 
  78             "Do you really want to close this application?",
  79             "Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
  80         result = dlg.ShowModal()
  81         dlg.Destroy()
  82         if result == wx.ID_OK:
  83             self.Destroy()
  85     def OnAbout(self, event):
  86         dlg = AboutBox()
  87         dlg.ShowModal()
  88         dlg.Destroy()  
  90 app = wx.App(redirect=True)   # Error messages go to popup window
  91 top = Frame("<<project>>")
  92 top.Show()
  93 app.MainLoop()

A Bare-Bones Application

The following is a minimum wxPython application in the tradition of Hello World:

   1 import wx
   3 app = wx.App(redirect=True)
   4 top = wx.Frame(None, title="Hello World", size=(300,200))
   5 top.Show()
   6 app.MainLoop()

Sub-Classing the Frame

It is common practice use an object-orientated approach as shown here. However, a procedural structure is equally valid and is shown in a subsequent section. To develop this application further you need to add your own frame object before you can add functionality to the wx.Frame.

   1 import wx
   3 class Frame(wx.Frame):
   4     def __init__(self, title):
   5         wx.Frame.__init__(self, None, title=title, size=(350,200))
   7 app = wx.App(redirect=True)
   8 top = Frame("Hello World")
   9 top.Show()
  10 app.MainLoop()

If you are not very familiar with using objects in Python you should look closely at this example as sub-classing is used quite frequently in wxPython. In this example the Frame class is based on wx.Frame. Any functions that appear in the derived class will hide those of the same name in the base class. This commonly applies to the __init__ function that is called automatically when a new object is defined. In this case the statement is top = Frame("Hello World"). It is necessary for the derived class to call the __init__ function in the base class explicitly. Note that the first argument is self so that the base class knows what object is being initialized.

Adding an Event Handler

   1 class Frame(wx.Frame):
   2     def __init__(self, title):
   3         wx.Frame.__init__(self, None, title=title, size=(350,200))
   4         self.Bind(wx.EVT_CLOSE, self.OnClose)
   6     def OnClose(self, event):
   7         dlg = wx.MessageDialog(self, 
   8             "Do you really want to close this application?",
   9             "Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
  10         result = dlg.ShowModal()
  11         dlg.Destroy()
  12         if result == wx.ID_OK:
  13             self.Destroy()

This example shows how to add a function that will handle the wx.EVT_CLOSE event that is generated when the user clicks on the X icon on the title bar of the frame. The Bind() function tells the event loop the name of the function to call when the event is detected. It is a useful convention to start the name of any event handlers with "On". This helps to ensure that the function name does not clash with one in the base class.

The OnClose function illustrates how to use a message dialog. The ShowModal function not only displays the dialog but also waits for the user to click on one of the buttons. The result is either wx.ID_OK or wx.ID_CANCEL. The Destroy function is used to terminate the application when the OK button is pressed. If self.Close() had been used instead of self.Destroy() the program would get into a loop as a further wx.EVT_CLOSE event would be issued.

An Alternative Program Structure

Since there is only one wx.Frame object there is no need to sub-class it and you can write the whole program as a simple procedure. Since the event handler, OnClose() is no longer a member function of the frame object there is no self argument and so global variables are used instead.

   1 import wx
   3 def OnClose(event):
   4     dlg = wx.MessageDialog(top, 
   5         "Do you really want to close this application?",
   6         "Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
   7     result = dlg.ShowModal()
   8     dlg.Destroy()
   9     if result == wx.ID_OK:
  10         top.Destroy()
  12 app = wx.App(redirect=True)
  13 top = wx.Frame(None, title="Hello World", size=(300,200))
  14 top.Bind(wx.EVT_CLOSE, OnClose)
  15 top.Show()
  16 app.MainLoop()

Adding Content to the Frame

This example shows how to add a menu bar, a status bar and a panel containing a button. The menu bar has only a single File menu but this is extended with a Help menu in the final example.

   1 class Frame(wx.Frame):
   2     def __init__(self, title):
   3         wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(350,200))
   4         self.Bind(wx.EVT_CLOSE, self.OnClose)
   6         menuBar = wx.MenuBar()
   7         menu = wx.Menu()
   8         m_exit = menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Close window and exit program.")
   9         self.Bind(wx.EVT_MENU, self.OnClose, m_exit)
  10         menuBar.Append(menu, "&File")
  11         self.SetMenuBar(menuBar)
  13         self.statusbar = self.CreateStatusBar()
  15         panel = wx.Panel(self)
  16         box = wx.BoxSizer(wx.VERTICAL)
  18         m_text = wx.StaticText(panel, -1, "Hello World!")
  19         m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
  20         m_text.SetSize(m_text.GetBestSize())
  21         box.Add(m_text, 0, wx.ALL, 10)
  23         m_close = wx.Button(panel, wx.ID_CLOSE, "Close")
  24         m_close.Bind(wx.EVT_BUTTON, self.OnClose)
  25         box.Add(m_close, 0, wx.ALL, 10)
  27         panel.SetSizer(box)
  28         panel.Layout()

The full example is based on the wxPython template that is used in the Luke-SDK IDE.

wxPython by Example (last edited 2012-06-28 08:10:48 by SWM-HIGH-SPEED2-22)