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.4 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()

BEGIN_EVENT_TABLE(MyFrame, wxFrame)

EVT_MENU(ID_Quit, MyFrame::OnQuit) EVT_MENU(ID_About, MyFrame::OnAbout) END_EVENT_TABLE()

IMPLEMENT_APP(MyApp)

MyFrame *frame = new MyFrame("Hello World", wxPoint(50,50)

wxSize(450,34 0)); 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!" );

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

■ 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 wxWindow base 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 preexisting 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.

Was this article helpful?

0 0

Post a comment