wxPython, a GUI Toolkit

You'll feel much better after reading about this new cross-platform toolkit written in Python and wrapped around wxWindows.

The installation of wxPython is fairly straightforward if you have a Debian or an RPM-based system, as Robin Dunn provides both of these packages on his web page at http://wxpython.org/. You'll need wxGTK installed (again, a package is provided) as well as Mesa-3.0.


We are now going to look at some simple wxPython examples. The intention is not to offer a tutorial but to get a feel for the way wxPython can be used.

Getting Started

The obligatory “hello world” application is shown in Listing 1. A fixed-size frame is created at line 14. A panel is attached to the frame at line 18, and within the panel, a static text area displaying “Hello world of wxPython” in the default font is created in lines 19-20. The application subclass definition is shown on lines 23-32. An instance of our frame is created, shown and brought to the foreground. If these definitions are run stand-alone, rather than being imported in another application, an instance of an application class is defined and run in lines 36-37.

Listing 1.

Note the systematic use of the object-oriented framework even in this very simple example. The frame and the application are subclasses of the pre-defined classes. We need to redefine only the methods we use to get our program working. A screen shot of this impressive application is shown in Figure 1.

Figure 1. ScreenShot of the “Hello” Application

One might say that about 40 lines of code is too many for a simple application that basically does nothing. In fact, you could probably cut this down to a few lines, but the goal is to present a relatively well-structured piece of code which is easy to build upon.

There are many function calls with -1 given as second argument, such as panel = wxPanel(self, -1). In these cases, the value of -1 is a mandatory numerical identifier for the object being created, which is used when connecting widgets together, as we will see in the second example. A value of -1 means “default” and is useful when this object ID will not be used anywhere in the code.

Slightly More Complicated Example

In the previous example, the position of the widget in the window was fixed, and we had no control over the application other than through the window manager: no menu, no exit button, etc. Moreover, getting the “hello world” message is a bit boring, so here's an application that does more and is much longer. The application is shown in Listing 2. In this second example, the structure of the program is essentially the same: we have a subclassed Frame and a subclassed Application. The subclassed Frame redefines the __init__ function. In the redefined __init__, we define a few more interesting messages than “hello” on line 13-18, a counting variable on line 19, a menu table on lines 20-25. As before, we call the parent's __init__ function on line 27, create a panel on line 30, some static text field on line 31 and a button on line 34. Lines 36-43 are devoted to the layout of the main part of the window. Basically, we have the static text in a fixed position; underneath it is a button, at the bottom of the window, that remains centered with respect to the right and left part of the window, no matter how wide the window is. This is done using a number of wxBoxSizer objects. On line 45, we associate a button event between the button defined on line 42 and the OnButtonClick method defined on line 69. This method will be called when the button is pressed.

Listing 2.

On line 47, we associate the application close event with the OnCloseWindow method, defined on line 76. Using this method, we build a quick message dialog box to ask the user for confirmation. On lines 48-64, we create a status line where the menu tool tips will be displayed. The main menu of applications is defined by the specs in myMenuTable, lines 20-25. Note that the “New” menu item will also call the method of line 81. In the definition of the menu items (lines 24-29), the character & before a letter indicates a keyboard shortcut (typing ALT + the letter calls the menu item).

On lines 65-67, we make the window layout fit together and set the autofit feature of the wxBoxSizer objects “on”. Lines 69-72 define the callback method from both the menu item and the button. This method simply redefines the text content of the static text object defined on line 31. Pressing the button multiple times shows the strings defined in self.myFortunes, line 13-18, in succession. The method of lines 87-88 is called from the “Exit” menu item and invokes the Close event, which will close the application. Lines 90-106 are identical to the “hello” example. A screen shot of this application is shown in Figure 2.

Figure 2. ScreenShots of the “Cookie” Application on Linux (a) and Windows (b)

The more interesting points of this “toy” application are how window layout can be achieved (using wxBoxSizer) and how events and widgets are connected (using EVT_MENU and EVT_BUTTON in this case). In fact, as it is, only the layout of the button is satisfactory; the main text is still in a fixed position—a complete solution would be too long to show here.

Note the use of the self.something variables. If a variable is to be accessed across methods, it must be called in this way (self being the object instance). If a variable is private to a method, the self prefix is not necessary.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Anonymous's picture

Nice examples, however how about removing the line numbers?

Try this

Mitch Frazier's picture

This should remove the lines numbers from the listings if you download them and save them to disk:

sed -e 's/^[0-9]* //' -i listing.py

Mitch Frazier is an Associate Editor for Linux Journal.