wxPython, a cross-platform GUI Library
Abstract
- In this document, we present a cross-platform GUI (Graphical User Interface) called wxPython . We shall be using wxPython 2.2.5 . We shall also introduce a few advanced topics that make the strength of wxPython. This document is available in several formats, including
PostScript, PDF, HTML and plain ASCII, from the Python HOWTO page at py-howto. The aim of the "Getting Started" guide is to teach the essentials of wxPython, partially by describing how wxPython works, and partially by providing useful and fully-working application which you can use as a model. It does not attempt to exhaustively describe every aspect of wxPython -- only the very core elements which every wxPython programmer needs to know are covered here. For more detailed descriptions of various topics, see the wxPython Cookbook.
- Table of Contents:
Contents
- wxPython, a cross-platform GUI Library
- Abstract
- What is wxPython ?
- Prerequisites
- Installation
- A First Application: "Hello, World"
- Building a wxPython Application
- Working with Windows
- Responding to User Actions
- Drawing
- Using wxPython
- Next Steps
- Useful resources
- As a conclusion- slithering our way to the future of GUI-apps
- Contributors
- Appendix
- Comments
- Comment Sample
- OS independent path concatenation
- OS independent path concatenation (part 2)
- small correction
- Correction to "adding the edit component" code snippet
- typo fix
- indentation fix
- Use the sizer in one step
- Mac specific fix for Hello World example
- RFE: Make the wiki spell checker happy about this page
- Code fix
- How to get tabs to work
- Examples update for wxPython 2.4/Python 2.3
- Spotted a possible error in the "Examples update for wxPython 2.4/Python 2.3" above
- In wxPython 2.4 and higher, you don't need to call SetAutoLayout()
- Various comments
What is wxPython ?
WxPython ranks amongst the toolkits that enable writing cross-platform GUI-applications along with pyQT , pyGTK , or Tkinter . But under windows, and unlike Tkinter or pyGTK, a wxPython Application has a look and feel very similar to what you would get with an application using microsoft native GUI, MFC [1]. This is because wxPython is a fine layer over the native GUI classes. Besides this, wxPython is very simple to learn and takes advantage of the possibilities Python is offering. For instance, events handling is particularly nice under wxPython. In fact, wxPython is simply (?) Python Bindings to a C++ Library called wxWidgets formerly called wxWindows); dating back from 1992 [2], wxWidgets is now a very stable, efficient, object-oriented library running (smoothly) on Windows, Unix ( GTK/Motif/Lesstif) and soon Macintosh.
[1] Microsoft Foundation Classes
[2] It's almost as old as Tkinter - which dates back from 1990
Prerequisites
- We assume the reader has sufficient knowledge of Python and is familiar with classes and objects in Python [3]. No other knowledge is required.
[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
- Installation under windows is especially simple: Run the installer you
can get from wxPython and follow the instructions.
Linux - Redhat
- You can find RPMs for Redhat (they are working just fine with Mandrake
through), at the address wxPython
Linux - Debian
wxPython can be installed through apt-get by calling apt-get install python-wxgtk2.4 or apt-get install python-wxgtk2.6, depending on which version you want. The wxPython demo is in the wx-examples package. Install it with apt-get install wx2.4-examples or apt-get install wx2.6-examples. Once it is installed, you need to copy /usr/share/doc/wx2.[4|6]-examples/examples/wxPython to a directory which you can edit. You then need to unzip each compressed file. You can do it with a script such as this one:
for i in *.gz; do gunzip $i doneYou can then run the demo by typing python demo.py.
Linux - Gentoo
wxPython can be installed through portage by calling emerge wxPython (notice the capital P). The correct command is actually emerge wxpython (without a capital p) as of 11/28/04.
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
- Untar wxGTK by type the command:
tar -xvzf wxGTK-2.2.5.tar.gz
- Go into the directory:
cd wxGTK-2.2.5
- Run the configure script:
./configure --with-gtk
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)
- Run the make file:
make
- You might get some errors here if yacc or lex are not installed. (in a Mandrake distribution, the right rpms are byacc-1.9-7mdk.i586.rpm and flex-2.5.4a-13mdk.i586.rpm)
You should now have a compiled version of wxGTK. We want to install it and link it into the system.
- Become superuser:
su
Your root password is required here.
- Install wxGTK:
make install
- Link the library:
ldconfig
- Exit from superuser mode:
exit
Normally, wxGTK is installed but there might be a problem with wxPython:
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:
- Go in to the directory where you want the library to be installed:
cd /usr/lib
- Create a symbolic link to the library:
ln -s /usr/local/lib/libwx_gtk.so
Installing wxPython
- Download the source code of the last wxPython release:
- Untar the tarball:
tar -xvzf wxPython-2.2.5.tar.gz
- go into the directory:
cd wxPython-2.2.5
- Edit the setup.py to choose what you want to install. I suggest that you don't install OGL and GL_CANVAS. by selecting:
BUILD_GLCANVAS = 0 # If true, build the contrib/glcanvas extension module BUILD_OGL = 0 # If true, build the contrib/ogl extension module BUILD_STC = 1 # If true, build the contrib/stc extension module CORE_ONLY = 0 # if true, don't build any of the above GL_ONLY = 0 # Only used when making the -gl RPM. See the "b" script # for the ugly details USE_SWIG = 0 # Should we actually execute SWIG, or just use the # files already in the distribution? IN_CVS_TREE = 0 # Set to true if building in a full wxWindows CVS # tree, otherwise will assume all needed files are # available in the wxPython source distribution - Build the python module:
python setup.py build
- Become root:
su
Your root password is required here.
- Install the module:
python setup.py install
- Exit root mode:
exit
- Check if the module works:
[lucas@b007 wxPython-2.2.5]$ python Python 1.5.2 (#1, Sep 30 2000, 18:08:36) [GCC 2.95.3 19991030 (prerelease)] on linux-i386 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import wx >>>
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"
- As is traditional, we are first going to write a Small "Hello, world" application. Here is the code:
import wx app = wx.PySimpleApp() frame = wx.Frame(None, wx.ID_ANY, "Hello World") frame.Show(True) app.MainLoop()
- Here is what you should get with wxGTK:
After importing the wx Python GUI module, we instantiate a new wx.PySimpleApp and a new wx.Frame. A frame in wxPython is a window with its titlebar, reduction and close buttons, etc... [4] We make this Frame appear by "showing" it. Eventually, we start the application's MainLoop whose role is to handle the events. Notice the shape of the constructor of wx.Frame:
1 wx.Frame(Parent, Id, "Hello World")
- Most of the constructors in wxPython have this shape: A parent object as a first parameter and an Id in a second parameter. As shown in the
example, it's possible to use respectively None and wx.ID_ANY as default parameters. (Meaning the object has no parent or respectively a system-defined Id)
[4] it can be a normal application window, a MDI parent frame, etc...
Building a wxPython Application
Topics:
- Creating a wxWindows application
- Structuring your application so that it can handle multiple documents.
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
When people talk of graphical user interfaces, they usually talk about things like windows, menus, the mouse, icons, etc. Naturally enough, then, you might assume that a wx.Window object represents a window on the computer screen. But you'd be wrong. In wxPython, a wx.Window is anything which can take up visual space on the computer screen. Thus, the wx.Window class is the base class from which all visual elements are derived -- including input fields, pull-down menus, etc. The wx.Window class defines all the behaviour common to all visual GUI elements, including positioning, sizing, showing, giving focus, etc. If you're looking for an object to represent a window on the computer screen, don't look at wx.Window; look at wx.Frame instead. wx.Frame (which is derived from wx.Window) implements all behaviour specific to windows on the computer's screen (and within an MDI interface -- but that's another story). So to create a window on the computer screen, you create a wx.Frame (or one of its sub-classes, such as wx.Dialog), rather than a wx.Window. Think in terms of frames, not windows, and you'll be fine.
A Working Example
Adding the edit component
- The first step is to add a new edit component to our hello world application. [5]
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()(Note that since the frame now shows itself in its init method, you no longer have to call frame.Show() explicitly, as in the first example.) As you can see, it is not very difficult: All we have to do is to derive wxFrame and then overwrite its __init__ method. In this method, we declare a new wx.TextCtrl, which is a simple text edit control. You will want to have a look at the demos that are bundled with the install package. They deal with all sorts of subjects and show how easy and rich wxPython is.
[5] The code herein appears, courtesy of Mr Michael Roberts. See also his excellent article in useful resources section.
Adding a menu
- Every application should have a menu bar and a status bar. Let's add them to ours:
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()
- The only little problem is that our application does little more than showing our new menu: As it is, our menu is a stillborn, devoid of any reaction. Let's implement reactions into our program:
Practical event handling
- Reacting to events in wxPython is called event handling. Flexible event handling is one of the biggest strengths of wxPython. We are going to present practical basic event handling and we'll discuss later in advanced topics, the how and why. An event is a small message sent by wxPython to your application to signify that "something" has happened [6]. Most often, in wxPython, all you have to do, is to "connect" an event with a particular method. This is done by calling
the pseudo methods EVT_*. (Also see Avoiding EVT_MENU.) For instance:
1 EVT_MENU(self, ID_ABOUT, self.OnAbout)
- In other words, from now on, any menu selection event with ID,
ID_ABOUT that is sent to window self, will be passed to the method self.OnAbout. The latter method has the general declaration:
1 def OnAbout(self, event):
2 ...
where event is an instance of a subclass of wxEvent. When this kind of method receives an event, there are two things that it can do:
- Skip the event, i.e. let it go through the hierarchy of event handlers.
Handle or catch (don't Skip) the event, i.e. the event will stop here after the callback function finishes. (
This is default behaviour) You "Skip" an event by calling the method event.Skip()
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
- Of course an editor is useless if it is not able to save or open documents. That's where Common dialogs come in. Common dialogs are those offered by the underlying platform so that your application will look exactly like a native application. Here is the implementation of
the OnOpen method in MainWindow :
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()
- This method works just in three steps:
- First, we create the dialog by calling the appropriate Constructor.
Then, we call the ShowModal method, that does all the real work and returns a value corresponding to what the user has pressed (OK button or Cancel)
- If necessary, we retrieve the filename and the directory of the selected file and we load it into the editor. Finally, we destroy the dialog.
the menu and connect it to the OnOpen method. Find the complete source in the appendix.
Possible extensions
- Of course, this program is far from being a decent editor. But adding other features should not be any more difficult than what has already been done. You might take inspiration from the demos that are bundled with wxPython:
- Drag and Drop.
- MDI
- Tab view/multiple files
- Find/Replace dialog
Print dialog (Printing)
- Macro-commands in python ( using the eval function)
- etc ...
Working with Windows
Topics:
- Frames
- Windows
- Controls/Widgets
- Sizers
- Validators
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
- Within a frame, you'll use a number of wxWindow sub-classes to flesh out the frame's contents. Here are some of the more common elements you might want to put in your frame:
A wxMenuBar, which puts a menu bar along the top of your frame.
A wxStatusBar, which sets up an area along the bottom of your frame for displaying status messages, etc.
A wxToolBar, which puts a toolbar in your frame.
Sub-classes of wxControl. These are objects which represent user interface widgets (ie, visual elements which display data and/or process user input). Common examples of wxControl objects include wxButton, wxStaticText, wxTextCtrl and wxComboBox.
A wxPanel, which is a container to hold your various wxControl objects. Putting your wxControl objects inside a wxPanel means that the user can tab from one UI widget to the next.
All visual elements (wxWindow objects and their subclasses) can hold sub-elements. Thus, for example, a wxFrame might hold a number of wxPanel objects, which in turn hold a number of wxButton, wxStaticText and wxTextCtrl objects, giving you an entire hierarchy of elements:
Note that this merely describes the way that certain visual elements are interrelated -- not how they are visually laid out within the frame. To handle the layout of elements within a frame, you have several options: - You can manually position each element by specifying it's exact pixel coordinate within the parent window. Because of differences in font sizes, etc, between platforms, this option is not generally recommended.
You can use wxLayoutConstraints, though these are fairly complex to use.
You can use the Delphi-like LayoutAnchors, which make it easier to use wxLayoutConstraints.
- You can use one of the wxSizer subclasses.
TODO: Add description for other element placement schemes???. To get the first impression about other element placement schemes: http://wxpython.org/tut-part2.php
Sizers
A sizer (that is, one of the wxSizer sub-classes) can be used to handle the visual arrangement of elements within a window or frame. Sizers can:
- Calculate an appropriate size for each visual element.
- Position the elements according to certain rules.
- Dynamically resize and/or reposition elements when a frame is resized.
wxBoxSizer, which arranges visual elements in a line going either horizontally or vertically.
wxGridSizer, which lays visual elements out into a grid-like structure.
wxFlexGridSizer, which is similar to a wxGridSizer except that it allow for more flexibility in laying out visual elements.
A sizer is given a list of wxWindow objects to size, either by calling sizer.Add(window, options...), or by calling sizer.AddMany(...). A sizer will only work on those elements which it has been given. Sizers can be nested. That is, you can add one sizer to another sizer, for example to have two rows of buttons (each laid out by a horizontal wxBoxSizer) contained within another wxBoxSizer which places the rows of buttons one above the other, like this:
Note: Notice that the above example does not lay out the six buttons into two rows of three columns each -- to do that, you should use a wxGridSizer.
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()
The sizer.Add method has three arguments. The first one specifies the control to include in the sizer. The second one is a weight factor which means that this control will be sized in proportion to other ones. For example, if you had three edit controls and you wanted them to have the proportions 3:2:1 then you would specify these factors as arguments when adding the controls. 0 means that this control or sizer will not grow. The third argument is normally wxGROW (same as wxEXPAND) which means the control will be resized when necessary. If you use wxSHAPED instead, the controls aspect ratio will remain the same.
If the second parameter is 0, i.e. the control will not be resized, the third parameter may indicate if the control should be centered horizontally and/or vertically by using wxALIGN_CENTER_HORIZONTAL, wxALIGN_CENTER_VERTICAL, or wxALIGN_CENTER (for both) instead of wxGROW or wxSHAPED as that third parameter.
You can alternatively specify combinations of wxALIGN_LEFT, wxALIGN_TOP, wxALIGN_RIGHT, and wxALIGN_BOTTOM. The default behavior is equivalent to wxALIGN_LEFT | wxALIGN_TOP.
One potentially confusing aspect of the wxSizer and its sub-classes is the distinction between a sizer and a parent window. When you create objects to go inside a sizer, you do not make the sizer the object's parent window. A sizer is a way of laying out windows, it is not a window in itself. In the above example, all six buttons would be created with the parent window being the frame or window which encloses the buttons -- not the sizer. If you try to create a visual element and pass the sizer as the parent window, your program will crash.
- Once you have set up your visual elements and added them to a sizer (or to a nested set of sizers), the next step is to tell your frame or window to use the sizer. You do this in three steps:
1 window.SetSizer(sizer)
2 window.SetAutoLayout(true)
3 sizer.Fit(window)
The SetSizer() call tells your window (or frame) which sizer to use. The call to SetAutoLayout() tells your window to use the sizer to position and size your components. And finally, the call to sizer.Fit() tells the sizer to calculate the initial size and position for all its elements. If you are using sizers, this is the normal process you would go through to set up your window or frame's contents before it is displayed for the first time.
Menus
TODO:
Validators
When you create a dialog box or other input form, you can use a wxValidator to simplify the process of loading data into your form, validating the entered data, and extracting the data out of the form again. wxValidator can also be used to intercept keystrokes and other events within an input field. To use a validator, you have to create your own sub-class of wxValidator (neither wxTextValidator nor wxGenericValidator are implemented in wxPython). This sub-class is then associated with your input field by calling myInputField.SetValidator(myValidator).
Note: Your wxValidator sub-class must implement the wxValidator.Clone() method.
A Working Example
Our first label within a panel
- Let's start with an example. Our program is going to have a single Frame with a panel [7] containing a label [8]:
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()
- This design should be clear and you should not have any problem with it if you read the Small Editor section of this howto. Notice in the line:
1 self.quote = wx.StaticText(self, -1, "Your quote :",wx.Point(20, 30))
the use of self as parent parameter of our wxStaticText. Our Static text is going to be on the panel we have created just before. The second parameter refers to the Id number of the new control. As this static control is not really going to be sending events, we don't care about this parameter. The wxPoint is used as positioning parameter. There is also an optional wxSize parameter but its use here is not justified.
[7] According to wxPython documentation:
- "A panel is a window on which controls are placed. It is usually placed within a frame. It contains minimal extra functionality over and above its parent class wxWindow; its main purpose is to be similar in appearance and functionality to a dialog, but with the flexibility of having any window as a parent.", in fact, it is a simple window used as a (grayed) background for other objects which are meant to deal with data entry. These are generally known as Controls or Widgets.
[8] A label is used to display text that is not supposed to interact with the user.
Adding a few more controls
- You will find a complete list of the numerous Controls that exist in wxPython in the demo and help, but here we are going to present those most frequently used:
wxButton The most basic Control: A button showing a text that you can click. Use the connector-function to handle a click on the button:
1 EVT_BUTTON(Control, Id, callback function)
wxTextCtrl This control let the user input a small line of text (In its single line version at least...). It generates two main events:
1 EVT_TEXT(control, Id ,callback function )
- That is called when the text has changed.
1 EVT_CHAR(control,callback function )
- That is called to signify that a key has been pressed.
wxComboBox A combobox is very similar to wxTextCtrl but in addition to the events generated by wxTextCtrl, wxComboBox has the handler:
1 EVT_COMBOBOX(control, id, callback function)
wxCheckBox The checkbox is a control that gives the user true/false choice.
wxRadioBox The radiobox lets the user choose from a list of options.
Let's have a closer look at what Form1 looks like now:
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 <