LanguagesWhat Can wxPython Do?

What Can wxPython Do?

Nearly all of your interface needs can be filled by wxPython. In this section, we’ll show you what some of the wxPython toolkit looks like, using pictures from elements of the wxPython demo application. Figure 1 is a composite image showing all the basic widgets you’d expect: buttons, checkboxes, a combo box, menus, list box, a spinner control, text controls and radio buttons.

Figure 2 shows less common, but very useful widgets, including a slider control, an editable list box, a time selector, a toolbar, a notebook control, a tree list control, and an analog clock.

The grid control is one of wxPython’s most flexible widgets, allowing custom rendering and editing of cells. Figure 3 shows an example of many of the features of the grid control.

And that’s not all-you also get a quite fully featured HTML-rendering widget that you can use for static styled text, as the base of a simple web browser, as a help system, or anything else you might want to display HTML for. An example is shown in figure 4.

We’ve only just scratched the surface. The wxPython library also includes tools for image animation. You also get clipboard and drag-and-drop support, support

Figure 1. A sampling of basic user interface controls, including menus, list boxes, and text controls.

Figure 2. More advanced interface controls, including a tree list and an analog clock.

Figure 3. The mega-grid example, showing custom grid cell rendering.

Figure 4. The wx.HTMLWindow, showing some of the HTML rendering capability.

for MIME types and audio, all the standard dialogs offered by your system, the ability to specify an interface definition in an XML file, full control over the layout of your windows, and more.

Why choose wxPython?

The most powerful benefit of wxPython depends on your needs and expertise. While we think that all user interface (UI) programmers would benefit from using wxPython, the specific features that are most helpful will vary from case to case.

Python programmers

If you are already a Python programmer, you’ve probably noticed that Tkinter, the interface toolkit distributed with Python, has some problems:

  • Tkinter is based on the Tk toolkit, which is somewhat out-of-date in terms of the kinds of widgets it supports. By default, it doesn’t support more complex widgets such as tree controls or tabbed windows. It also doesn’t have a particularly rich set of predefined dialogs.
  • The Tk toolkit does not use native widget support, resulting in an application that looks foreign on all platforms. In wxPython, dialogs and widgets will look like those that are standard on the underlying operating system. Your Tk user will find that buttons, fonts, and menus all look slightly different from what might be expected.
  • Many programmers find Tkinter itself somewhat clunky to work with. In particular, the process by which events are translated to actions in wxPython is more flexible and powerful.

You’ll find that wxPython solves these problems. The toolkit in wxPython is vastly more complete and extensive than that of Tkinter and the native widget support means your application will look at home in your operating system. Additionally, the Python language support is more fluid in wxPython, making for a somewhat nicer programming experience.

wxWidget users

If you are already using wxWidgets, then what wxPython has to offer you is the Python language itself. With its clear syntax, dynamic typing, and flexible object model, Python can improve your productivity dramatically. Python has a very extensive standard library that is easily incorporated into your application, and Python programs tend to be shorter and less error-prone than C++ programs. There are also a number of Python-only additions to the wxWidgets tool set.

New users

If you’re not currently using either Python or wxWidgets, you’re in for a real treat, since you’ll get the benefit of both the extensive toolkit and the Python language. If you are currently working in Java/Swing, you’ll probably find wxPython less complex and easier to use, and the Python language significantly less verbose than Java. If you are currently using a single-platform C++ toolkit like the Microsoft Foundation Classes (MFC), then you’ll appreciate the cross-platform nature of wxPython. In order to follow the examples in this book, however, some Python familiarity is helpful. If you need to get started on Python itself, try The Quick Python Book, by Daryl Harms and Kenneth McDonald.

In the next section, you’ll learn about the component pieces of wxPython: the Python language itself, and the wxWidgets toolkit. You’ll also learn about the rationale and implementation of wxPython itself.

How wxPython works

In the previous section, we talked about what wxPython can do. In this section, we’ll take a closer look at how wxPython works. Internally, wxPython is a wrapper or interface for a popular C++ interface toolkit called wxWidgets. The wxWidgets project has a long history and is the source of most of the functionality of wxPython. Using wxPython allows you to get the benefits of the wxWidgets toolkit, while being able to use Python rather than C++.

The wxPython toolkit is the combination of two distinct pieces of software, which have over 25 years of development between them. In addition, the wxPython toolkit itself was the result of a significant amount of work. To make wxPython go, a tool called SWIG is used to generate wrapper functions, or glue code, which allow a Python program to use the C++ wxWidgets library just as if it were any old Python library. Although SWIG does a lot of the work, there’s still some hand-tooling needed to make the wxPython objects look and act like other Python objects.

There have also been several additional widgets written directly in wxPython that are not available in the C++ version of the tool-you’ll encounter several of them along the way in this book.

In this section we will provide a brief overview of the Python programming language and the wxWidgets C++ toolkit. It is the combination of Python’s ease of use and wxWidgets’ range of functionality that gives wxPython its unique power.

The Python language

Python is a programming language which is easily able to handle both the scripting tasks normally associated with Perl and the full-scale application development normally associated with C++ or Java. Using a simple, elegant, concise, syntax and a clean, consistent, semantic model, Python allows programmers to easily combine simple pieces to make a complex whole.

Throughout the rest of this book, it’s assumed that you have a good working knowledge of Python, and are familiar with basic concepts such as how Python implements objects and classes. You don’t need to be a Python expert to read this book, but ordinary Python language constructs are not explained in the discussion of the wxPython examples. If you need more background information on Python, the Python web site contains an excellent tutorial and other documentation at www.python.org/doc.

One important Python feature is the interactive interpreter, which can be very helpful in exploring the language and in debugging programs. If Python is installed and on your path, you can access the interpreter by entering python at a command prompt. You’ll then see >>> , which is the Python command prompt. From there, you can enter any Python expression, and its value will be displayed on the screen. For example:

$ python
Python 2.3.3c1 (#50, Dec 4 2003, 21:27:34) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 + 2
4
>>> 10 / 3
3
>>> zip(['a', 'b', 'c'], [1, 2, 3])
[('a', 1), ('b', 2), ('c', 3)]
>>>
 

In this short session, I did a couple of simple arithmetic functions, then used the Python built-in function zip(), to combine two lists into an associated list. You can do anything from the interpreter that you can do in a standalone Python program, including import modules, define functions, and define classes.

The wxWidgets toolkit

The other base component of wxPython is the wxWidgets toolkit. At base, wxWidgets is a GUI framework implemented in C++, which means it is a set of C++ classes that encapsulate a wide range of features. Although the primary use of wxWidgets is for UI applications, it also contains useful features for C++ programmers including C++ implementations of data structures not supported in ANSI C++, such as strings and hashtables, as well as interfaces for system features like sockets and threads. Since these features and others are already available in the Python language or standard library, wrappers for these wxWidgets classes are not provided in wxPython and you should use the Python equivalents instead. For the most part wxPython only provides wrappers for the GUI classes in wxWidgets. The goal of wxWidgets is to allow a C++ program to compile and run on all supported platforms with only minor changes to the source from platform to platform, and a reasonably consistent look and feel between the platforms.

Here’s a sample C++ wxWidgets program, taken from Robert Roebling’s tutorial on the wxWidgets site. This creates a blank window with a two-element menu, Quit and About. This is being shown primarily for comparison with the Python examples we’ll be seeing throughout the book.

Listing 1. A simple Hello World program in C++ wxWidgets

#include "wx/wx.h"
class MyApp: public wxApp {
virtual bool OnInit();
};
class MyFrame: public wxFrame {
public:
MyFrame(const wxString& title, const wxPoint& pos,
const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
enum {
ID_Quit = 1,
ID_About,
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() {
MyFrame *frame = new MyFrame("Hello World", wxPoint(50,50),
wxSize(450,340));
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos,
const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size) {
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWidgets!" );
}
Listing 1.4 A simple Hello World program in C++ wxWidgets
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) {
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) {
wxMessageBox("This is a wxWidgets Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION, this);
}

If you’re familiar with C++, you probably noticed that something is missing. Usually, C++ programs have a function named main() which is the starting point for the program. In wxWidgets, the macro IMPLEMENT_APP(MyApp) automatically sets up a default main()which manages initialization of the wxWidget program.

As with most cross-platform interface kits, the classes and methods visible to the programmer are actually proxies for a set of subclasses. Typically there is a subclass for each platform that wxWidgets runs under, and the subclass specific to the current platform is automatically used. As of this writing, these are the most significant supported platforms:

  • Microsoft Windows
  • Mac OS
  • Gnome Toolkit (GTK+), which is applicable on most modern Unix systems

For each platform, wxWidgets attempts to use native widgets and features where applicable, and generally tries to emulate the native look and feel. In this way, wxWidgets avoids the “least common denominator” problem that cross-platform toolkits frequently have.

If you are familiar with any other large-scale object-oriented interface toolkit, such as MFC or Java Swing, the basic structure of wxWidgets should feel largely similar. One difference from some toolkits is that wxWidgets does not make a class distinction between widgets that can contain other widgets and ones that can’t. (The way that, for example, Java Swing has a JComponent and JContainer class). The mechanism for adding child widgets is built into the wxWindowbase class so that it is potentially available to all widgets, whether or not they are typically thought of as containers. Typically, though, widgets that are not containers prevent you from using this behavior (you can’t put a dialog box inside a button, for example).

Development of wxWidgets goes back farther than you might think. The project was begun in 1992 by Julian Smart, at the University of Edinburgh’s Artificial Intelligence Applications Institute. Smart was trying to build an application that could run on both Unix and Windows, and the existing commercial toolkits were prohibitively expensive, so he wrote his own. The name wxWidgets refers to the two original platforms-“w” for Microsoft Windows and “x” for Unix X server. The original version was written in terms of MFC, for the Windows version, and XView on Unix, but that quickly gave way to more general libraries for each platform as XView was replaced by the Motif toolkit, and MFC was replaced with direct calls to the Windows API. In 1997, the entire system was built with a more flexible API, and the GTK+ version became the standard Unix port soon after. The Macintosh port came on board the next year. More recent developments in the wxWidget side include a Unix library which is not dependent on a pre-existing toolkit, and ports for handheld systems.

Python is not the only language which has a binding library for wxWidgets, although it has the largest user community of the group. The wxWidgets web site links to projects with support for Ada, Basic, C#, Eiffel, Euphoria, Haskell, Java, JavaScript, Lua, Perl, and Ruby, although we make no claims for the robustness or level of support of any of those ports.

Putting it together: the wxPython toolkit

While both Python and wxWidgets are pretty great on their own, they combine to create an even greater whole, like peanut butter and chocolate. The flexibility of the Python language makes wxPython much easier to develop in than its C++ counterpart, while the native C++ code of wxWidgets gives the Python GUI both the speed and native look and feel it would otherwise lack. Table 1 gives a sample of some issues that are difficult to manage in C++ but easy, if not trivial, in Python.

Table 1. Developing in C++ versus developing in wxPython

C++ environment wxPython environment
Memory management handled by programmer Memory management handled by Python
Static typing makes polymorphism difficult Dynamic typing makes polymorphism easy
Program reflection very limited Program reflection easy, allowing for powerful abstraction
Unable to use functions as arguments easily Functions can be passed around like any other variable
Compilation cycle needed before each run Program interpreted at runtime

Here is an example of how the two tools interact. In the previous section, we showed you a “hello world” example in C++ wxWidgets. Listing 2 shows the same example translated basically line-by-line into wxPython.

Listing 2. A simple Hello World program in wxPython

import wx
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame("Hello World", (50, 60), (450, 340))
frame.Show()
self.SetTopWindow(frame)
return True
class MyFrame(wx.Frame):
def __init__(self, title, pos, size):
wx.Frame.__init__(self, None, -1, title, pos, size)
menuFile = wx.Menu()
menuFile.Append(1, "&About...")
menuFile.AppendSeparator()
menuFile.Append(2, "E&xit")
menuBar = wx.MenuBar()
menuBar.Append(menuFile, "&File")
self.SetMenuBar(menuBar)
self.CreateStatusBar()
self.SetStatusText("Welcome to wxPython!")
self.Bind(wx.EVT_MENU, self.OnAbout, id=1)
self.Bind(wx.EVT_MENU, self.OnQuit, id=2)
def OnQuit(self, event):
self.Close()
def OnAbout(self, event):
wx.MessageBox("This is a wxPython Hello world sample",
"About Hello World", wx.OK | wx.ICON_INFORMATION, self)
if __name__ == '__main__':
app = MyApp(False)
app.MainLoop()

There are two high-level things that we’d like to point out about the wxPython example compared to the wxWidgets C++ one (beyond merely the difference between the two languages).

First, notice that wxPython does not have the automatic macro for creating a main starting point, and must do so explicitly at the end of this module.

Second, the mechanism for associating events with the code to be executed is different between the two programs. Since Python allows functions to be passed easily around as objects, the wxPython program can use the relatively straightforward wx.Bind() methods to do the associating dynamically at runtime. The C++ program must use the DECLARE_EVENT_TABLE and BEGIN_EVENT_TABLEmacros, which do the binding statically at compile time and are somewhat more awkward.

Beyond those changes, the two programs are quite similar line by line-we find the Python version more readable, though. As you’ll see, Python becomes more of an advantage in larger programs, due to its simpler syntax, automatic memory management, and so forth. At this point it’s worth mentioning that wxPython did not come about by accident. It was developed to fill a specific need for a cross-platform rapid development environment. It has prospered and advanced because of the continued efforts of programmers who need rapid GUI development.

Development of wxPython and wxWidgets continues. Ongoing projects include support for mobile devices and better multimedia support. The most current version of wxPython is available at www.wxpython.org.

Summary

  • You can create a minimal wxPython program in less than 10 lines of code. Most wxPython programs are much longer than 10 lines, and are typically divided into separate modules, each containing customized subclasses of wxPython classes, and, hopefully, plenty of docstrings.
  • Most of the wxPython toolkit is accessed through the wx package which you access using the import wx statement. Every wxPython program must have an application object-an instance of a wx.App subclass that defines an OnInit() method. Most wxPython programs will have one or more frames- instances of subclasses of wx.Frame. A frame is the large, movable, resizeable window-like container that appears on screen, often with a menu, status bar, tool bars, and other widgets. Control of your program passes to wxPython when you call your application’s MainLoop()method.
  • Within wxPython are all the basic widgets you would expect, plus common dialogs, a wide variety of more complex widgets, HTML rendering, spreadsheet- style grids, and so forth. The wxWidgets toolkit that wxPython is based on is a C++ framework with a large list of features. It is a cross-platform toolkit, with most support for Microsoft Windows, Unix GTK+, and the Mac OS. The basic unit of a wxWidgets application is the window, meaning any item that can be drawn to the screen.
  • The wxPython toolkit is a combination of the Python programming language and the wxWidgets toolkit and can be downloaded at www. wxpython.org. It combines a very extensive interface toolkit with an easy-touse scripting language. It offers productivity gains and useful features for any programmer, including existing Python or wxWidgets programmers.
  • The wxPython version of the toolkit is a wrapper around wxWidgets containing bindings which allow Python language constructs to interact with the C++ framework. These bindings are largely created from the SWIG tool, from a long list of descriptions of how Python objects and C++ objects relate to each other.

About the Authors

Noel Rappinis a senior software engineer at a large technology company, and has extensive Python experience. He has a Ph.D. from the Georgia Institute of Technology, where he studied educational software and user interface design. Noel co-authored the book Jython Essentials.

Robin Dunn, the creator and maintainer of wxPython, has been working in the software industry for 18 years on a wide variety of applications. He discovered both wxWindows and Python in 1995 while looking for a cross platform toolkit and has never (willingly) looked back. Robin was awarded the ActiveState Programmers? Choice Award at the 2002 O?Reilly Open Source Convention. Robin also worked for the Open Source Applications Foundation, improving wxPython for use in their flagship product, Chandler.

Source of This Material

wxPython in Action
By Noel Rappin and Robin Dunn

Published: March 2006, 620 pages
Published by Manning Publications
ISBN: 1932394621
PDF ebook: $25.00
Softbound book + PDF ebook : $49.95

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories