Home |
Last modified: 30-10-2009 |
wxWidgets, formerly known as wxWindows, is an open-source, cross-platform framework which uses the target OS' native widgets to achieve native look and feel. wxPython is a thin layer above the wxWidgets framework.
wxApp -> wxFrame -> wxPanel -> wxSizer -> wxControl
If you work under Windows, the best choice is to install ActiveState's version of Python: It includes Python as available on www.python.org, Windows-specific add-on's like access to the Win32 API and COM, along with a few other items like BerkeleyDB.The Enthought version includes a lot of stuff that are probably not useful to most developers, but you might need those. FWIW, the so-called "Python IDE" that comes with ActiveState is just a graphical command-line interface to Python; Nothing like rich IDE's like Delphi or VB. You may need to add the path to the Python folder to the PATH environment variable.
Once Python is installed, install wxPython. It contains wxWidgets, so you don't need to download both. Make sure you download the wxPython package that matches the version of Python that you installed previously, eg. 2.4.x or 2.5.x (the wxPython installer will tell you if it can't find the right version anyway.) As an option, you can download the documentation and demos from the site. In Windows Explorer, double-click on "C:\Program Files\wxPython2.6 Docs and Demos\demo\demo.py" to run the demo.
If you choose to use UltraEdit to work with Python and want to add support for syntax highlighting, wordfiles are available on the site for various versions of Python. As alternate IDE's built for Python, take at look at Stani's Python Editor (SPE; It includes the wxGlade GUI designer) or ActiveState's Komodo.
This will show you how to launch your very first wxPython script in Windows:
"When most people look at this running program, they see something they would call a “window.” However, wxPython does not call this a window. It calls this a “frame.” In wxPython,“window” is the generic term for any object that displays on the screen (what other toolkits might call a “widget”). So, a wxPython programmer will often refer to objects such as buttons or text boxes as “windows.” This may seem confusing, but the usage dates to the earliest days of the original C++ toolkit, and it’s unlikely to change now. In this book, we’ll try to avoid the use of window as a generic term, because it’s confusing and also because it’s the name of a big product from a major corporation. We’ll use widget as the generic term. When we’re specifically referring to the operating system of similar name, we’ll do it with a capital “W.”"
Use a frame when you need a window for your application; Use a panel (within that frame) to place other widgets onto. Don't place (most) widgets right onto the frame itself; there are some problems with that. You can and often will use multiple panels within the same frame.
As an easy way to lay down widgets into a frame, use the wx*Sizer classes:
wxPython-speak for what is otherwise known in the Windows world as the tab widget, ie. multiple sub-windows on top of each other.
??
First, the obligatory "Hello, world!":
This can be used to launch a script when the user clicks on the button, and display information in the label:
Next, a basic editor (from wxPython for newbies):
Here's how to add a menu bar, and display a dialogbox when choosing an item:
Here, we'll build a filled window that contains a plane, ie. not just an empty frame, and add widgets on the plane:
What we generally call a window in Windows is called a frame in wxWidgets. In wxWidgets, windows refer to any widget within a frame.
A bare frame:
A more real-life structure:
If the application is so simple as to only need a single frame, there's an easier way to create an application:
A frame cannot be created before the application object. The most important use of ID numbers in wxPython is to create a unique relationship between an event that happens to a specific object and a function which is called in response to that event.
In real-life applications, widgets such as push-buttons are not created directly in a frame, but rather in a panel, which acts as a container and is itself created in a frame. A panel usually overlays the entire frame, and helps keeping the widgets separate from the toolbar and status bar. When a frame is created with just a single child window, that child window (typically, a panel) is automatically resized to fill the client area of the frame.
Use a sizer to avoid having to specify the position and size of each widget, including when the user resizes the frame/panel.
Common dialogs are available. Here's an example:
If you just need some basic, text input from the user:
If you want to have the user pick an item in a limited list:
Events are represented as instances of the wx.Event class and its subclasses, such as wx.CommandEvent and wx.MouseEvent. An event handler is a written function or method that is called in response to an event. Also called a handler function or handler method. An event binder is a wxPython object that encapsulates the relationship between a specific widget, a specific event type, and an event handler. In order to be invoked, all event handlers must be registered with an event binder.
PyCrust is a graphical shell program, written in wxPython, that you can use to help analyze your wxPython programs. PyCrust is part of a larger Py package that includes additional programs with related functionality including PyFilling, PyAlaMode, PyAlaCarte, and PyShell.
The key to a successful MVC design is not in making sure that every object knows about every other object. Instead, a successful MVC program explicitly hides knowledge about one part of the program from the other parts. The goal is for the systems to interact minimally, and over a well-defined set of methods. In particular, the Model component should be completely isolated from the View and Controller.
Because both refactoring and the use of an MVC design pattern tend to break your program into smaller pieces, it is easier for you to write specific unit tests targeting individual parts of your program. Since version 2.1, Python has been distributed with the unittest module. The unittest module implements a test framework called PyUnit.
The layout mechanism in wxPython is called a sizer, and the idea is similar to layout managers in Java AWT and other interface toolkits. Each different sizer manages the size and position of its windows based on a set of rules. The sizer belongs to a container window (typically a wx.Panel). Subwindows created inside the parent must be added to the sizer, and the sizer manages the size and position of each widget.
The primary wx.Frame class has several different frame style bits which can change its appearance. In addition, wxPython offers miniframes, and frames that implement the Multiple Document Interface (MDI). Frames can be split into sections using splitter bars, and can encompass panels larger than the frame itself using scrollbars.
A panel is an instance of the class wx.Panel, and is a simple container for other widgets with little functionality of its own. You should almost always use a wx.Panel as the top-level subwidget of your frame. For one thing, the extra level can allow greater code reuse, as the same panel and layout could be used in more than one frame. Using a wx.Panel gives you some of the functionality of a dialog box within the frame. This functionality manifests itself in a couple of ways. One is simply that wx.Panel instances have a different default background color under MS Windows operating systems—white, instead of gray. Secondly, panels can have a default item that is automatically activated when the Enter key is pressed, and panels respond to keyboard events to tab through the items or select the default item in much the same way that a dialog does.
Here's how to create an MDI parent/child interface:
A splitter window is a particular kind of container widget that manages exactly two sub-windows. The two sub-windows can be stacked horizontally or next to each other left and right. In between the two sub-windows is a sash, which is a movable border that changes the size of the two sub-windows. Splitter windows are often used for sidebars to the main window (i.e., a browser).
In wxPython, a wizard is a series of pages controlled by an instance of the class wx.wizard.Wizard. The wizard instance manages the events that take the user through the pages. The pages themselves are instances of either the class wx.wizard.WizardPageSimple or wx.wizard.WizardPage. In both cases, they are merely wx.Panel instances with the additional logic needed to manage the page chain.
A validator is a special wxPython object that simplifies managing data in a dialog. A validator is attached to a specific widget in your system.
The recommended way to deal with complicated layout these days is by using a sizer. A sizer is an automated algorithm for laying out a group of widgets. A sizer is attached to a container, usually a frame or panel. Subwidgets that are created within a parent container must be separately added to the sizer. When the sizer is attached to the container, it then manages the layout of the children contained inside it. The most flexible sizers, the grid bag and box, will be able to do nearly everything you’ll want them to. A wxPython sizer is an object whose sole purpose is to manage the layout of a set of widgets within a container. The sizer is not a container or a widget itself. It is just the representation of an algorithm for laying out a screen.
Predefined sizers:
p.325
Read Which is the best compiler to use with wxWindows 2? to check which compiler you'd rather work with if you are just getting started. A list of C compilers can be found here.
Just run the Windows installer, which will take care of uninstalling the current version, if need be.
Both widgets are located in the same frame. Why use self.button?
Rename the script from .py to .pyw.
It's a pain to have to TAB things right when copy/pasting code from the Net.
"The sizers are a basic tool in wxWidgets to get layouts to be mostly portable to other platforms where the widgets may be of different size. They are less important if you plan to develop for only one platform but its useful to get used to them as they can also aid when adding/removing elements from the design."