wxPython, a cross-platform GUI Library

Abstract

Contents

  1. wxPython, a cross-platform GUI Library
    1. Abstract
    2. What is wxPython ?
    3. Prerequisites
    4. Installation
      1. Windows
      2. Linux - Redhat
      3. Linux - Debian
      4. Linux - Gentoo
      5. Linux - Building from the source
        1. Installing Python
        2. Installing wxGTK
        3. Installing wxPython
      6. Mac OS X
    5. A First Application: "Hello, World"
    6. Building a wxPython Application
      1. Overview
      2. A Working Example
        1. Adding the edit component
        2. Adding a menu
        3. Practical event handling
        4. More magic
        5. Possible extensions
    7. Working with Windows
      1. Overview
        1. Laying out Visual Elements
        2. Sizers
        3. Menus
        4. Validators
      2. A Working Example
        1. Our first label within a panel
        2. Adding a few more controls
        3. The notebook
        4. Improving the layout - Using Sizers
    8. Responding to User Actions
      1. Overview
      2. A Working Example
    9. Drawing
      1. Overview
      2. A Working Example
    10. Using wxPython
      1. Debugging Techniques
      2. PyCrust interactive shell
      3. Deploying your wxPython Application
    11. Next Steps
      1. Events
      2. Scintilla
      3. Boa-constructor
      4. multi threading
      5. Managed/ Non Managed windows
    12. Useful resources
    13. As a conclusion- slithering our way to the future of GUI-apps
    14. Contributors
    15. Appendix
      1. Small editor - Complete Source
      2. Building Forms - Complete source
      3. Drawing with wxPython - Complete Source
      4. A rudimentary project organizer - Complete Source
    16. Comments
      1. Comment Sample
      2. OS independent path concatenation
      3. OS independent path concatenation (part 2)
      4. small correction
      5. Correction to "adding the edit component" code snippet
      6. typo fix
      7. indentation fix
      8. Use the sizer in one step
      9. Mac specific fix for Hello World example
      10. RFE: Make the wiki spell checker happy about this page
      11. Code fix
      12. How to get tabs to work
      13. Examples update for wxPython 2.4/Python 2.3
      14. Spotted a possible error in the "Examples update for wxPython 2.4/Python 2.3" above
      15. In wxPython 2.4 and higher, you don't need to call SetAutoLayout()
    17. Various comments

What is wxPython ?

[1] Microsoft Foundation Classes

[2] It's almost as old as Tkinter - which dates back from 1990

Prerequisites

[3] If you are not already a Pythonista, you might want to have a look at http://www.freenetpages.co.uk/hp/alan.gauld/

Installation

Windows

Linux - Redhat

Linux - Debian

Linux - Gentoo

Linux - Building from the source

You might also want to build wxPython from the source. You have to do this in three steps:

Installing Python

You should have already done that. Refer to the Python website to have some more information. ( BUILD.unix is probably the helpfile you are looking for )

Installing wxGTK

wxGTK is the GTK version of wxWidgets. GTK (Gimp ToolKit) is a graphic library used by Gnome, so it is probably already installed on your Linux box. All you have to do is download the wxGTK source from the wxGTK ftp server. Or the wxWidgets website

You might get some errors here if GTK is not installed or if the include files for GTK are not installed (in a Mandrake distribution, gtk+-devel-1.2.8-6mdk.i586.rpm is the rpm that you want to install)

You should now have a compiled version of wxGTK. We want to install it and link it into the system.

Your root password is required here.

it is possible that the library is not installed where wxPython is looking for it. ( In a mandrake 7.2 distribution, you want wxGTK to be installed in /usr/lib whereas it is automatically installed in /usr/local/lib) The solution is to create a symbolic link of the library where you want it to be:

Installing wxPython

wxPython website

Your root password is required here.

wxPython is fully installed!

Mac OS X

An installer is available on the wxPython site, for both PPC and Intel Macs.

If you wish to build it yourself, you should follow the instruction described here.

A french howto can be found here

A First Application: "Hello, World"

import wx
app = wx.PySimpleApp()
frame = wx.Frame(None, wx.ID_ANY, "Hello World")
frame.Show(True)
app.MainLoop()

   1         wx.Frame(Parent, Id, "Hello World")

[4] it can be a normal application window, a MDI parent frame, etc...

Building a wxPython Application

In this section, we shall build a little editor. This is mostly to convince you of the inner capabilities and of the simplicity of use of wxPython. If you are already convinced you might as well want to read the Advanced Topics first.

Overview

A Working Example

Adding the edit component

import wx
class MainWindow(wx.Frame):
    """ We simply derive a new class of Frame. """
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(200,100))
        self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE)
        self.Show(True)
app = wx.PySimpleApp()
frame=MainWindow(None, wx.ID_ANY, 'Small editor')
app.MainLoop()

[5] The code herein appears, courtesy of Mr Michael Roberts. See also his excellent article in useful resources section.

Adding a menu

   1 import wx
   2 ID_ABOUT=101
   3 ID_EXIT=110
   4 class MainWindow(wx.Frame):
   5     def __init__(self,parent,id,title):
   6         wx.Frame.__init__(self,parent,wx.ID_ANY, title, size = (200,100))
   7         self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE)
   8         self.CreateStatusBar() # A Statusbar in the bottom of the window
   9         # Setting up the menu.
  10         filemenu= wx.Menu()
  11         filemenu.Append(ID_ABOUT, "&About"," Information about this program")
  12         filemenu.AppendSeparator()
  13         filemenu.Append(ID_EXIT,"E&xit"," Terminate the program")
  14         # Creating the menubar.
  15         menuBar = wx.MenuBar()
  16         menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
  17         self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
  18         self.Show(True)
  19 app = wx.PySimpleApp()
  20 frame = MainWindow(None, -1, "Sample editor")
  21 app.MainLoop()

Practical event handling

   1 EVT_MENU(self, ID_ABOUT, self.OnAbout)

   1 def OnAbout(self, event):
   2         ...

Now let's have a look at our application:

   1 import os
   2 import wx
   3 ID_ABOUT=101
   4 ID_EXIT=110
   5 class MainWindow(wx.Frame):
   6     def __init__(self,parent,id,title):
   7         wx.Frame.__init__(self,parent,wx.ID_ANY, title, size = (200,100))
   8         self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE)
   9         self.CreateStatusBar() # A StatusBar in the bottom of the window
  10         # Setting up the menu.
  11         filemenu= wx.Menu()
  12         filemenu.Append(ID_ABOUT, "&About"," Information about this program")
  13         filemenu.AppendSeparator()
  14         filemenu.Append(ID_EXIT,"E&xit"," Terminate the program")
  15         # Creating the menubar.
  16         menuBar = wx.MenuBar()
  17         menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
  18         self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
  19         wx.EVT_MENU(self, ID_ABOUT, self.OnAbout) # attach the menu-event ID_ABOUT to the
  20                                                            # method self.OnAbout
  21         wx.EVT_MENU(self, ID_EXIT, self.OnExit)   # attach the menu-event ID_EXIT to the
  22                                                            # method self.OnExit
  23         self.Show(True)
  24     def OnAbout(self,e):
  25         d= wx.MessageDialog( self, " A sample editor \n"
  26                             " in wxPython","About Sample Editor", wx.OK)
  27                             # Create a message dialog box
  28         d.ShowModal() # Shows it
  29         d.Destroy() # finally destroy it when finished.
  30     def OnExit(self,e):
  31         self.Close(True)  # Close the frame.
  32 app = wx.PySimpleApp()
  33 frame = MainWindow(None, -1, "Sample editor")
  34 app.MainLoop()

[6] the mouse has been moved, a key has been pressed, the user has popped up the menu, everything you might possibly think of...

More magic

   1     def OnOpen(self,e):
   2         """ Open a file"""
   3         self.dirname = ''
   4         dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN)
   5         if dlg.ShowModal() == wx.ID_OK:
   6             self.filename=dlg.GetFilename()
   7             self.dirname=dlg.GetDirectory()
   8             f=open(os.path.join(self.dirname,self.filename),'r')
   9             self.control.SetValue(f.read())
  10             f.close()
  11         dlg.Destroy()

Possible extensions

Working with Windows

In this section, we are going to present the way wxPython deals with windows and their contents, including building input forms and using various widgets/controls. We are going to build a small application that calculates the price of a quote. If you are already an experienced GUI developer, this is going to be easy and you might want to move on to the Boa-Constructor Subsection in the Advanced topics chapter.

Overview

Laying out Visual Elements

Sizers

   1 import wx
   2 import os
   3 ID_ABOUT=101
   4 ID_OPEN=102
   5 ID_BUTTON1=110
   6 ID_EXIT=200
   7 class MainWindow(wx.Frame):
   8     def __init__(self,parent,id,title):
   9         self.dirname=''
  10         wx.Frame.__init__(self,parent,wx.ID_ANY, title)
  11         self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE)
  12         self.CreateStatusBar() # A Statusbar in the bottom of the window
  13         # Setting up the menu.
  14         filemenu= wx.Menu()
  15         filemenu.Append(ID_OPEN, "&Open"," Open a file to edit")
  16         filemenu.AppendSeparator()
  17         filemenu.Append(ID_ABOUT, "&About"," Information about this program")
  18         filemenu.AppendSeparator()
  19         filemenu.Append(ID_EXIT,"E&xit"," Terminate the program")
  20         # Creating the menubar.
  21         menuBar = wx.MenuBar()
  22         menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
  23         self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
  24         wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)
  25         wx.EVT_MENU(self, ID_EXIT, self.OnExit)
  26         wx.EVT_MENU(self, ID_OPEN, self.OnOpen)
  27         self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
  28         self.buttons=[]
  29         for i in range(0,6):
  30             self.buttons.append(wx.Button(self, ID_BUTTON1+i, "Button &"+`i`))
  31             self.sizer2.Add(self.buttons[i],1,wx.EXPAND)
  32         # Use some sizers to see layout options
  33         self.sizer=wx.BoxSizer(wx.VERTICAL)
  34         self.sizer.Add(self.control,1,wx.EXPAND)
  35         self.sizer.Add(self.sizer2,0,wx.EXPAND)
  36         #Layout sizers
  37         self.SetSizer(self.sizer)
  38         self.SetAutoLayout(1)
  39         self.sizer.Fit(self)
  40         self.Show(1)
  41     def OnAbout(self,e):
  42         d= wx.MessageDialog( self, " A sample editor \n"
  43                             " in wxPython","About Sample Editor", wx.OK)
  44                             # Create a message dialog box
  45         d.ShowModal() # Shows it
  46         d.Destroy() # finally destroy it when finished.
  47     def OnExit(self,e):
  48         self.Close(True)  # Close the frame.
  49     def OnOpen(self,e):
  50         """ Open a file"""
  51         dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN)
  52         if dlg.ShowModal() == wx.ID_OK:
  53             self.filename=dlg.GetFilename()
  54             self.dirname=dlg.GetDirectory()
  55             f=open(os.path.join(self.dirname, self.filename),'r')
  56             self.control.SetValue(f.read())
  57             f.close()
  58         dlg.Destroy()
  59 app = wx.PySimpleApp()
  60 frame = MainWindow(None, -1, "Sample editor")
  61 app.MainLoop()

   1 window.SetSizer(sizer)
   2 window.SetAutoLayout(true)
   3 sizer.Fit(window)

Menus

Validators

A Working Example

Our first label within a panel

   1 import wx
   2 class Form1(wx.Panel):
   3     def __init__(self, parent, id):
   4         wx.Panel.__init__(self, parent, id)
   5         self.quote = wx.StaticText(self, -1, "Your quote :", wx.Point(20, 30), wx.Size(200, -1))
   6 app = wx.PySimpleApp()
   7 frame = wx.Frame(None, -1, " Our first Control")
   8 Form1(frame,-1)
   9 frame.Show(1)
  10 app.MainLoop()

   1         self.quote = wx.StaticText(self, -1, "Your quote :",wx.Point(20, 30))

[7] According to wxPython documentation:

[8] A label is used to display text that is not supposed to interact with the user.

Adding a few more controls

   1 EVT_BUTTON(Control, Id, callback function)

   1 EVT_TEXT(control, Id ,callback function )

   1 EVT_CHAR(control,callback function )

   1 EVT_COMBOBOX(control, id, callback function)

   1 import wx
   2 class Form1(wx.Panel):
   3     def __init__(self, parent, id):
   4         wx.Panel.__init__(self, parent, id)
   5         self.quote = wx.StaticText(self, -1, "Your quote :",wx.Point(20, 30))
   6         <