Wxpython Tutorial
Wxpython Tutorial
Audience
This tutorial is designed for software programmers who are keen on learning how to
develop GUI applications for the desktop.
Prerequisites
You should have a basic understanding of computer programming terminologies. A basic
understanding of Python and any of the programming languages is a plus.
wxPython
Table of Contents
About the Tutorial .................................................................................................................................... i
Audience .................................................................................................................................................. i
Prerequisites ............................................................................................................................................ i
Disclaimer & Copyright............................................................................................................................. i
Table of Contents .................................................................................................................................... ii
1.
WXPYTHON INTRODUCTION............................................................................................. 1
2.
ENVIRONMENT.................................................................................................................... 2
Windows ................................................................................................................................................. 2
Linux ....................................................................................................................................................... 2
MacOS..................................................................................................................................................... 2
3.
4.
5.
6.
7.
8.
EVENT HANDLING.............................................................................................................. 15
9.
wxPython
wxPython
iv
1. wxPython Introduction
wxPython
wxPython is a Python wrapper for wxWidgets (which is written in C++), a popular crossplatform GUI toolkit. Developed by Robin Dunn along with Harri Pasanen, wxPython is
implemented as a Python extension module.
Just like wxWidgets, wxPython is also a free software. It can be downloaded from the
official website http://wxpython.org. Binaries and source code for many operating system
platforms are available for download on this site.
Principal modules in wxPython API include a core module. It consists of wxObject class,
which is the base for all classes in the API. Control module contains all the widgets used
in GUI application development. For example, wx.Button, wx.StaticText (analogous to a
label), wx.TextCtrl (editable text control), etc.
wxPython API has GDI (Graphics Device Interface) module. It is a set of classes used for
drawing on widgets. Classes like font, color, brush, etc. are a part of it. All the container
window classes are defined in Windows module.
Official website of wxPython also hosts Project Phoenix a new implementation of
wxPython for Python 3.*. It focuses on improving speed, maintainability, and extensibility.
The project began in 2012 and is still in beta stage.
2. Environment
wxPython
Windows
Prebuilt binaries for Windows OS (both 32 bit and 64 bit) are available on
http://www.wxpython.org/download.php page. Latest versions of installers available are:
wxPython3.0-win32-3.0.2.0-py27.exe for 32-bit Python 2.7
wxPython3.0-win64-3.0.2.0-py27.exe for 64-bit Python 2.7
wxPython demo, samples and wxWidgets documentation is also available for download on
the same page.
wxPython3.0-win32-docs-demos.exe
Linux
wxPython binaries for many Linux distros can be found in their respective repositories.
Corresponding package managers will have to be used to download and install. For
instance on Debian Linux, following command should be able to install wxPython.
sudo apt-get install python-wxgtk3.0
MacOS
Prebuilt binaries for MacOS in the form of disk images are available on the download page
of the official website.
3. Hello World
wxPython
A simple GUI application displaying Hello World message is built using the following steps:
Import wx module.
Create a top level window as object of wx.Frame class. Caption and size parameters
are given in constructor.
Although other controls can be added in Frame object, their layout cannot be
managed. Hence, put a Panel object into the Frame.
Add a StaticText object to display Hello World at a desired position inside the
window.
import wx
app = wx.App()
window = wx.Frame(None,title="wxPython Frame",size=(300,200))
panel=wx.Panel(window)
label=wx.StaticText(panel,label="Hello World",pos=(100,50))
window.Show(True)
app.MainLoop()
The above code produces the following output:
wxPython
wxFrame object is the most commonly employed top level window. It is derived from
wxWindow class. A frame is a window whose size and position can be changed by the
user. It has a title bar and control buttons. If required, other components like menu bar,
toolbar and status bar can be enabled. A wxFrame window can contain any frame that is
not a dialog or another frame.
4. wx.Frame Class
wxPython
wx.Frame Class has a default constructor with no arguments. It also has an overloaded
constructor with the following parameters:
Wx.Frame (parent, id, title, pos, size, style, name)
Parameter
Description
Parent
id
Title
Pos
Size
style
name
wxPython
Example
window=wx.Frame(None, -1, Hello, pos=(10,10), size=(300,200), style=
wxDEFAULT_FRAME_STYLE, name=frame)
GetMenuBar()
GetStatusBar()
SetMenuBar()
setStatusBar()
SetToolBar()
SetStatusText()
Create()
Centre()
SetPosition()
SetSize()
SetTitle()
EVT_MENU_OPEN
EVT_MENU_CLOSE
EVT_MENU_HIGHLIGHT
5. wx.Panel Class
wxPython
Widgets such as button, text box, etc. are placed on a panel window. wx.Panel class is
usually put inside a wxFrame object. This class is also inherited from wxWindow class.
Although controls can be manually placed on panel by specifying the position in screen
coordinates, it is recommended to use a suitable layout scheme, called sizer in wxPython,
to have better control over the placement and address the resizing issue.
In wxPanel constructor, the parent parameter is the wx.Frame object in which the panel
is to be placed. Default value of id parameter is wx.ID_ANY, whereas the default style
parameter is wxTAB_TRAVERSAL.
wxPython API has the following sizers, using which controls are added into a panel object:
wx.BoxSizer
wx.StaticBoxSizer
wx.GridSizer
wx.FlexGridSizer
Control added in cell grid can occupy more than one cell
wx.GridBagSizer
Sizer object is applied as the layout manager of the panel using SetSizer() method of
wxPanel class.
wx.Panel.SetSizer(wx.???Sizer())
wxPython
Creating a good looking GUI by manual coding can be tedious. A visual GUI designer tool
is always handy. Many GUI development IDEs targeted at wxPython are available.
Following are some of them:
wxFormBuilder
wxDesigner
wxGlade
BoaConstructor
gui2py
wxPython
Add necessary controls in the Box with suitable captions. Here, a StaticText (label), two
TextCtrl objects (text boxes) and a wxButton object are added. The frame looks like the
following image:
wxPython
Enable Expand and Stretch on these three controls. In the object properties for wxButton
object, assign a function findsquare() to OnButtonClick event.
Save the project and press F8 to generate Python code for developed GUI. Let the
generated file be named as Demo.py
10
wxPython
In the executable Python script, import demo.py and define FindSquare() function. Declare
Application object and start a main event loop. Following is the executable code:
import wx
class CalcFrame(demo.MyFrame1):
def __init__(self,parent):
demo.MyFrame1.__init__(self,parent)
def FindSquare(self,event):
num = int(self.m_textCtrl1.GetValue())
self.m_textCtrl2.SetValue (str(num*num))
app = wx.App(False)
frame = CalcFrame(None)
frame.Show(True)
#start the applications
app.MainLoop()
The above code produces the following output:
11
7. Major Classes
wxPython
Original wxWidgets (written in C++) is a huge class library. GUI classes from this library
are ported to Python with wxPython module, which tries to mirror the original wxWidgets
library as close as possible. So, wx.Frame class in wxPython acts much in the same way
as wxFrame class in its C++ version.
wxObject is the base for most of the classes. An object of wxApp (wx.App in wxPython)
represents the application itself. After generating the GUI, application enters in an event
loop by MainLoop() method. Following diagrams depict the class hierarchy of most
commonly used GUI classes included in wxPython.
12
wxPython
13
wxPython
14
8. Event Handling
wxPython
Unlike a console mode application, which is executed in a sequential manner, a GUI based
application is event driven. Functions or methods are executed in response to users
actions like clicking a button, selecting an item from collection or mouse click, etc., called
events.
Data pertaining to an event which takes place during the applications runtime is stored
as object of a subclass derived from wx.Event. A display control (such as Button) is the
source of event of a particular type and produces an object of Event class associated to it.
For instance, click of a button emits a wx.CommandEvent. This event data is dispatched
to event handler method in the program. wxPython has many predefined event binders.
An Event binder encapsulates relationship between a specific widget (control), its
associated event type and the event handler method.
For example, to call OnClick() method of the program on a buttons click event, the
following statement is required:
self.b1.Bind(EVT_BUTTON, OnClick)
Bind() method is inherited by all display objects from wx.EvtHandler class. EVT_.BUTTON
here is the binder, which associates button click event to OnClick() method.
Example
In the following example, the MoveEvent, caused by dragging the top level window a
wx.Frame object in this case is connected to OnMove() method using wx.EVT_MOVE
binder. The code displays a window. If it is moved using mouse, its instantaneous
coordinates are displayed on the console.
import wx
class Example(wx.Frame):
def InitUI(self):
self.Bind(wx.EVT_MOVE, self.OnMove)
self.SetSize((250, 180))
self.SetTitle('Move event')
self.Centre()
self.Show(True)
15
wxPython
ex = wx.App()
Example(None)
ex.MainLoop()
Some of the subclasses inherited from wx.Event are listed in the following table:
wxKeyEvent
wxPaintEvent
wxMouseEvent
16
wxPython
wxScrollEvent
wxCommandEvent
wxMenuEvent
wxColourPickerEvent
wxDirFileickerEvent
Events in wxPython are of two types. Basic events and Command events. A basic event
stays local to the window in which it originates. Most of the wxWidgets generate command
events. A command event can be propagated to window or windows, which are above
the source window in class hierarchy.
Example
Following is a simple example of event propagation. The complete code is:
import wx
class MyPanel(wx.Panel):
def btnclk(self,e):
print "Button received click event. propagated to Panel class"
e.Skip()
class Example(wx.Frame):
17
wxPython
def __init__(self,parent):
super(Example, self).__init__(parent)
self.InitUI()
def InitUI(self):
mpnl = MyPanel(self)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
ex = wx.App()
Example(None)
ex.MainLoop()
In the above code, there are two classes. MyPanel, a wx.Panel subclass and Example, a
wx.Frame subclass which is the top level window for the program. A button is placed in
the panel.
This Button object is bound to an event handler btnclk() which propagates it to parent
class (MyPanel in this case). Button click generates a CommandEvent which can be
propagated to its parent by Skip() method.
MyPanel class object also binds the received event to another handler OnButtonClicked().
This function in turn transmits to its parent, the Example class. The above code produces
the following output:
18
wxPython
19
9. Layout Management
wxPython
A GUI widget can be placed inside the container window by specifying its absolute
coordinates measured in pixels. The coordinates are relative to the dimensions of the
window defined by size argument of its constructor. Position of the widget inside the
window is defined by pos argument of its constructor.
import wx
app = wx.App()
window = wx.Frame(None,title="wxPython Frame",size=(300,200))
panel=wx.Panel(window)
label=wx.StaticText(panel,label="Hello World",pos=(100,50))
window.Show(True)
app.MainLoop()
This Absolute Positioning however is not suitable because of the following reasons:
The position of the widget does not change even if the window is resized.
The appearance may not be uniform on different display devices with different
resolutions.
Modification in the layout is difficult as it may need redesigning the entire form.
wxPython API provides Layout classes for more elegant management of positioning of
widgets inside the container. The advantages of Layout managers over absolute
positioning are:
Layout manager is called Sizer in wxPython. Wx.Sizer is the base class for all sizer
subclasses. Let us discuss some of the important sizers such as wx.BoxSizer,
wx.StaticBoxSizer, wx.GridSizer, wx.FlexGridSizer, and wx.GridBagSizer.
20
10. wx.BoxSizer
wxPython
Add() method (inherited from wxSizer) appends it to the next row/column of the sizer.
Box.Add(control, proportion, flag, border)
The proportion parameter controls how the control changes it size in response to
dimensions of the container. Combination of various flag parameters decides the
appearance of control in the sizer. Following are some of the flags:
Alignment Flags
wx.ALIGN_TOP
wx.ALIGN_BOTTOM
wx.ALIGN_LEFT
wx.ALIGN_RIGHT
wx.ALIGN_CENTER_VERTICAL
wx.ALIGN_CENTER_HORIZONTAL
Border Flags
wx.TOP
wx.BOTTOM
wx.LEFT
wx.RIGHT
wx.ALL
21
wxPython
Behavior Flags
wx.EXPAND
wx.SHAPED
wx.FIXED_MINSIZE
Does not let the item become smaller than its initial
minimum size
wx.RESERVE_SPACE_EVEN_IF_
HIDDEN
The border parameter is an integer, the space in pixels to be left between controls. For
example,
b=wx.StaticText(self, -1, Enter a number)
Box.Add(b,1,wx.ALL|wx.EXPAND,10)
Following are some more methods of wx.BoxSizer class:
SetOrientation()
AddSpacer()
AddStretchSpacer()
Clear()
Detach()
Insert()
Remove()
Example
In the following code, a vertical box sizer is applied to a panel object which is placed inside
wxFrame window.
p=wx.Panel(self)
vbox=wx.wx.BoxSizer(wx.VERTICAL)
The first row in the box displays a label (wx.StaticText object) in the center with a border
of 20 pixels around it.
l1=wx.StaticText(p,label="Enter a number",style= wx.ALIGN_CENTRE )
vbox.Add(l1,0,
wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 20)
22
wxPython
In the second row, a wx.Button object is displayed. Because of wx.EXPAND flag it occupies
the entire width of the window.
b1=wx.Button(p, label="Btn1")
vbox.Add(b1,0,wx.EXPAND)
The next row also contains a button. It is not added with EXPAND flag. Instead, because
of ALIGN_CENTER_HORIZONTAL, button with default size appears in the center
horizontally.
b2=wx.Button(p, label="Btn2")
vbox.Add(b2,0,wx.ALIGN_CENTER_HORIZONTAL)
In the next row, a TextCtrl object with proportion parameter set to 1 and EXPAND flag set
is added. As a result, it is taller in size.
t=wx.TextCtrl(p)
vbox.Add(t,1,wx.EXPAND,10)
The last row holds a horizontal sizer object, which in turn has a label and button separated
by a stretchable space.
hbox=wx.BoxSizer(wx.HORIZONTAL)
l2=wx.StaticText(p,label="Label2",style= wx.ALIGN_CENTRE)
hbox.Add(l2,0,wx.EXPAND)
b3=wx.Button(p,label="Btn3")
hbox.AddStretchSpacer(1)
hbox.Add(b3,0,wx.ALIGN_LEFT,20)
vbox.Add(hbox,1,wx.ALL|wx.EXPAND)
Lastly, the vertical box sizer is applied to wx.Panel object.
Following is the complete code:
import wx
class Example(wx.Frame):
self.InitUI()
self.Centre()
self.Show()
23
wxPython
def InitUI(self):
p=wx.Panel(self)
vbox=wx.wx.BoxSizer(wx.VERTICAL)
l1=wx.StaticText(p,label="Enter a number",style= wx.ALIGN_CENTRE )
vbox.Add(l1,0,
wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 20)
b1=wx.Button(p, label="Btn1")
vbox.Add(b1,0,wx.EXPAND)
b2=wx.Button(p, label="Btn2")
vbox.Add(b2,0,wx.ALIGN_CENTER_HORIZONTAL)
t=wx.TextCtrl(p)
vbox.Add(t,1,wx.EXPAND,10)
hbox=wx.BoxSizer(wx.HORIZONTAL)
l2=wx.StaticText(p,label="Label2",style= wx.ALIGN_CENTRE)
hbox.Add(l2,0,wx.EXPAND)
b3=wx.Button(p,label="Btn3")
hbox.AddStretchSpacer(1)
hbox.Add(b3,0,wx.ALIGN_LEFT,20)
vbox.Add(hbox,1,wx.ALL|wx.EXPAND)
p.SetSizer(vbox)
app = wx.App()
Example(None, title='BoxSizer demo')
app.MainLoop()
24
wxPython
25
11. wx.GridSizer
wxPython
As the name suggests, a GridSizer object presents a two dimensional grid. Controls are
added in the grid slot in the left-to-right and top-to-bottom order. GridSizer object takes
four parameters:
wx.GridSizer(rows, columns, vgap, hgap)
vgap and hgap parameters control vertical and horizontal spacing between the adjacent
controls.
Following table shows some important methods of wxGridSizer class:
Add()
AddMany()
SetRows()
GetRows()
SetCols()
GetCols()
SetVGap()
GetVGap()
SetHGap()
GetHGap()
The following code demonstrates a simple gridsizer of a 4 by 4 grid with vertical and
horizontal gap of 5 pixels.
Gs = wx.GridSizer(4, 4, 5, 5)
Sixteen button objects are successively added using a for loop.
for i in range(1,17):
btn="Btn"+str(i)
gs.Add(wx.Button(p,label=btn),0,wx.EXPAND)
26
wxPython
class Example(wx.Frame):
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
p=wx.Panel(self)
gs = wx.GridSizer(4, 4, 5, 5)
for i in range(1,17):
btn="Btn"+str(i)
gs.Add(wx.Button(p,label=btn),0,wx.EXPAND)
p.SetSizer(gs)
app = wx.App()
Example(None, title='Grid demo')
app.MainLoop()
27
wxPython
28
12. wx.FlexiGridSizer
wxPython
This sizer also has a two dimensional grid. However, it provides little more flexibility in
laying out the controls in the cells. Although all the controls in the same row have the
same height, and all the controls in the same column have the same width, the size of
each cell is not uniform as in GridSizer.
Width and/or height of cells in a single column/row can be allowed to extend by
AddGrowableRow() and AddGrowableCol() method.
wx.FlexiGridSizer class constructor takes four parameters:
Wx.FlexiGridSizer(rows, cols, vgap, hgap)
A brief description of major methods of wx.FlexiGridSizer is given below:
AddGrowableCol()
AddGrowRow()
SetFlexibleDirection()
Example
A two-column form is designed with the following code. The first column contains labels
and the second contains text boxes. The second column is set to be growable. Similarly,
the third row is set to be growable. (Note that the row index and the column index starts
from 0). The second parameter in AddGrowableCol() and AddGrowableRow() function is
the proportion of growth.
fgs.AddGrowableRow(2, 1)
fgs.AddGrowableCol(1, 1)
The entire code is as follows:
import wx
class Example(wx.Frame):
self.InitUI()
29
wxPython
self.Centre()
self.Show()
def InitUI(self):
panel = wx.Panel(self)
hbox = wx.BoxSizer(wx.HORIZONTAL)
tc1 = wx.TextCtrl(panel)
tc2 = wx.TextCtrl(panel)
tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
fgs.AddGrowableRow(2, 1)
fgs.AddGrowableCol(1, 1)
app = wx.App()
Example(None, title='FlexiGrid Demo')
app.MainLoop()
wxPython
31
13. wx.GridBagSizer
wxPython
GetItemPosition()
SetItemPosition()
GetItemSpan()
SetItemSpan()
The following code displays a form in which there are labels (StaticText) associated with
textboxes (TexCtrl). TextCtrl objects are added with span parameter specified. Hence, the
width of text boxes spans more than one column. Text box for name spans over two
columns.
tc = wx.TextCtrl(panel)
sizer.Add(tc, pos=(0, 1), span=(1, 2), flag=wx.EXPAND|wx.ALL, border=5)
Textbox for address is a multiline text control spanning over three columns.
tc1 = wx.TextCtrl(panel,style=wx.TE_MULTILINE)
sizer.Add(tc1, pos=(1,1), span=(1, 3), flag=wx.EXPAND|wx.ALL, border=5)
The row containing multiline text control for description is set to be growable so that it
expands vertically downwards, if the form is stretched.
tc4 = wx.TextCtrl(panel,style=wx.TE_MULTILINE)
sizer.Add(tc4, pos=(3,1), span=(1,3), flag=wx.EXPAND|wx.ALL, border=5)
32
wxPython
sizer.AddGrowableRow(3)
class Example(wx.Frame):
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
panel = wx.Panel(self)
sizer = wx.GridBagSizer(0,0)
tc = wx.TextCtrl(panel)
sizer.Add(tc, pos=(0, 1), span=(1, 2), flag=wx.EXPAND|wx.ALL, border=5)
text2=wx.StaticText(panel,label="age")
sizer.Add(text2, pos=(2, 0), flag=wx.ALL,
border=5)
tc2=wx.TextCtrl(panel)
sizer.Add(tc2, pos=(2,1),flag=wx.ALL, border=5)
text3=wx.StaticText(panel,label="Mob.No")
sizer.Add(text3, pos=(2, 2), flag=wx.ALIGN_CENTER|wx.ALL, border=5)
33
wxPython
tc3=wx.TextCtrl(panel)
sizer.Add(tc3, pos=(2,3),flag=wx.EXPAND|wx.ALL, border=5)
panel.SetSizerAndFit(sizer)
app = wx.App()
Example(None, title='GridBag Demo')
app.MainLoop()
34
14. wx.StaticBoxSizer
wxPython
A StaticBoxSizer puts a box sizer into a static box. It provides a border around the box
along with a label at the top. Following steps are involved in preparing a statcboxsizer:
Example
In the following example, two staticbox sizers are created and added into a top vertical
box sizer, which controls the layout of the panel inside a frame.
The first staticbox sizer is created around a static box named Name.
nm = wx.StaticBox(panel, -1, 'Name:')
nmSizer = wx.StaticBoxSizer(nm, wx.VERTICAL)
A Horizontal box sizer, holding two labels and two text boxes, is added into nmSizer static
box sizer.
nmbox = wx.BoxSizer(wx.HORIZONTAL)
nmbox.Add(nm1, 0, wx.ALL|wx.CENTER, 5)
nmbox.Add(ln, 0, wx.ALL|wx.CENTER, 5)
nmbox.Add(nm2, 0, wx.ALL|wx.CENTER, 5)
35
wxPython
Two button objects, named ok and cancel are put in a horizontal box sizer, which in
turn, is placed inside the second staticbox sizer.
hbox=wx.BoxSizer(wx.HORIZONTAL)
okButton = wx.Button(panel, -1, 'ok')
hbox.Add(okButton, 0, wx.ALL|wx.LEFT, 10)
cancelButton = wx.Button(panel, -1, 'cancel')
hbox.Add(cancelButton, 0, wx.ALL|wx.LEFT, 10)
sboxSizer.Add(hbox, 0, wx.ALL|wx.LEFT, 10)
Two static box sizers, name and Buttons are added into a vertical box sizer acting as
the layout manager of the panel in the top level frame.
panel=wx.Panel(self)
vbox=wx.BoxSizer(wx.VERTICAL)
vbox.Add(nmSizer,0, wx.ALL|wx.CENTER, 5)
vbox.Add(sboxSizer,0, wx.ALL|wx.CENTER, 5)
panel.SetSizer(vbox)
Following is the complete code:
import wx
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title)
panel=wx.Panel(self)
vbox=wx.BoxSizer(wx.VERTICAL)
nm = wx.StaticBox(panel, -1, 'Name:')
nmSizer = wx.StaticBoxSizer(nm, wx.VERTICAL)
nmbox = wx.BoxSizer(wx.HORIZONTAL)
fn = wx.StaticText(panel, -1, "First Name")
nmbox.Add(fn, 0, wx.ALL|wx.CENTER, 5)
nm1 = wx.TextCtrl(panel, -1, style=wx.ALIGN_LEFT)
nm2 = wx.TextCtrl(panel, -1, style=wx.ALIGN_LEFT)
ln = wx.StaticText(panel, -1, "Last Name")
nmbox.Add(nm1, 0, wx.ALL|wx.CENTER, 5)
36
wxPython
nmbox.Add(ln, 0, wx.ALL|wx.CENTER, 5)
nmbox.Add(nm2, 0, wx.ALL|wx.CENTER, 5)
nmSizer.Add(nmbox, 0, wx.ALL|wx.CENTER, 10)
panel.Fit()
self.Show()
app = wx.App()
Mywin(None,
'staticboxsizer demo')
app.MainLoop()
The above code produces the following output:
37
15. Buttons
wxPython
Button widget is most widely used in any GUI interface. It captures the click event
generated by the user. Its most obvious use is to trigger a handler function bound to it.
wxPython class library provides different types of buttons. There is a simple, traditional
button, wx.Button class object, which carries some text as its caption. A two-state button
is also available, which is named as wx.ToggleButton. Its pressed or depressed state
can be identified by eventhandler function.
Another type of button, wx.BitmapButton displays a bitmap (image) as icon on its face.
Constructor for wx.Button class and wx.ToggleButton class takes the following arguments:
Wx.Button(parent, id, label, pos, size, style)
These are some important methods of wx.Button class:
SetLabel()
GetLabel()
SetDefault()
SetValue()
In order to create a bitmap button, firstly, a bitmap object needs to be constructed out of
an image file.
The following variation of wx.Bitmap class constructor is most commonly used:
Wx.Bitmap(fiiename, wx.BITMAP_TYPE)
wx.BITMAP_TYPE_BMP
wx.BITMAP_TYPE_ICO
wx.BITMAP_TYPE_CUR
wx.BITMAP_TYPE_TIFF
wx.BITMAP_TYPE_TIF
wx.BITMAP_TYPE_GIF
38
wxPython
wx.BITMAP_TYPE_PNG
wx.BITMAP_TYPE_JPEG
wx.BITMAP_TYPE_PCX
wx.BITMAP_TYPE_ICON
wx.BITMAP_TYPE_ANY
This bitmap object is used as one of the parameters for wx.BitmapButton class constructor.
Wx.BitmapButton(parent, id, bitmap, pos, size, style)
On some OS platforms, the bitmap button can display both bitmap and label. SetLabel()
methods assign the caption. On other platforms, it serves as an internal label.
The normal button as well bitmap button emits a wx.CommandEvent. EVT_BUTTON binder
associates a handler function to it.
The toggle button on the other hand uses wx.TOGGLEBUTTON binder for event handling.
In the following example, buttons of all three types are placed in a vertical box sizer of a
panel.
Simple button object is created using the statement:
self.btn=wx.Button(panel,-1,"click Me")
These buttons are added into vertical sizer using the following statements:
vbox.Add(self.btn,0,wx.ALIGN_CENTER)
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)
Note: Because of wx.EXPAND flag, the toggle button occupies the entire width of the
frame.
Using EVT_BUTTON and EVT_TOGGLEBUTTON binders they are associated with the
respective handlers.
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked)
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)
39
wxPython
Three bitmap buttons are added into a horizontal box sizer. These buttons display an
image as icon as their caption.
bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP)
self.bmpbtn = wx.BitmapButton(panel, id=wx.ID_ANY, bitmap=bmp,
size=(bmp.GetWidth()+10, bmp.GetHeight()+10))
40
wxPython
panel=wx.Panel(self)
vbox=wx.BoxSizer(wx.VERTICAL)
self.btn=wx.Button(panel,-1,"click Me")
vbox.Add(self.btn,0,wx.ALIGN_CENTER)
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked)
hbox=wx.BoxSizer(wx.HORIZONTAL)
wxPython
self.bmpbtn2.SetLabel("SAVE")
vbox.Add(hbox,1,wx.ALIGN_CENTER)
panel.SetSizer(vbox)
self.Centre()
self.Show()
self.Fit()
app = wx.App()
Mywin(None,
'Button demo')
app.MainLoop()
The above code produces the following output:
wxPython
Another important element in a GUI interface is a label, a read-only text of one or more
lines. It is usually placed on the frame either as an identifier of another widget or as an
informative string.
In wxPython, wx.StaticText class object presents a control holding such read-only text.
It can be termed as a passive control since it doesnt produce any event. Wx.StaticText
class constructor requires the following usual parameters:
Wx.StaticText(parent, id, label, position, size, style)
wx.ALIGN_CENTER
wx.ST_NO_AUTORESIZE
wx.ST_ELLIPSIZE_START
wx.ST_ELLIPSIZE_MIDDLE
wx.ST_ELLIPSIZE_END
GetLabel()
SetForeGroundColour()
SetBackGroundColour()
Wrap()
The above features of StaticText class are demonstrated in the following example. Three
StaticText objects are placed in a vertical box sizer.
The first object has multi-line text which is center aligned. The second labels text is set
to wrap around beyond 200 pixels. The third label shows ellipsis () in the middle of the
text.
43
wxPython
wx.FONTFAMILY_ROMAN
wx.FONTFAMILY_SCRIPT
wx.FONTFAMILY_SWISS
wx.FONTFAMILY_MODERN
wx.FONTFAMILY_TELETYPE
wx.FONTSTYLE_ITALIC
wx.FONTSTYLE_SLANT
Normal font
wx.FONTWEIGHT_LIGHT
Light font
wx.FONTWEIGHT_BOLD
Bold font
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title,size=(600,200))
44
wxPython
panel=wx.Panel(self)
box=wx.BoxSizer(wx.VERTICAL)
lbl=wx.StaticText(panel,-1,style=wx.ALIGN_CENTER)
txt1 = "Python GUI development"
txt2="using wxPython"
txt3=" Python port of wxWidget "
txt=txt1+"\n"+txt2+"\n"+txt3
font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
lbl.SetFont(font)
lbl.SetLabel(txt)
box.Add(lbl,0,wx.ALIGN_CENTER)
lblwrap=wx.StaticText(panel,-1,style=wx.ALIGN_RIGHT)
txt=txt1+txt2+txt3
lblwrap.SetLabel(txt)
lblwrap.Wrap(200)
box.Add(lblwrap,0,wx.ALIGN_LEFT)
lbl1=wx.StaticText(panel,-1, style=wx.ALIGN_LEFT | wx.ST_ELLIPSIZE_MIDDLE)
lbl1.SetLabel(txt)
lbl1.SetForegroundColour((255,0,0))
lbl1.SetBackgroundColour((0,0,0))
font=self.GetFont()
font.SetPointSize(20)
lbl1.SetFont(font)
box.Add(lbl1,0,wx.ALIGN_LEFT)
panel.SetSizer(box)
self.Centre()
self.Show()
app = wx.App()
Mywin(None,
'StaticText demo')
app.MainLoop()
45
wxPython
46
wxPython
In a GUI interface, the input is most commonly collected in a text box where the user can
type using the keyboard. In wxPython, an object of wx.TextCtrl class serves this purpose.
It is a control in which the text can be displayed and edited. The TextCtrl widget can be
a single line, multi-line or a password field. TextCtrl class constructor takes the following
form:
wx.TextCtrl(parent, id, value, pos, size, style)
The style parameter takes one or more constants from the following list:
wx.TE_MULTILINE
The text control allows multiple lines. If this style is not
specified, the line break characters should not be used in the controls value.
wx.TE_PASSWORD
wx.TE_READONLY
wxTE_LEFT
SetEditable()
SetMaxLength()
The following event binders are responsible for event handling related to entering text in
TextCtrl box:
EVT_TEXT
EVT_TEXT_ENTER
47
wxPython
EVT_TEXT_MAXLEN
Example
In the following example, four objects of wx.TextCtrl class with different attributes are
placed on the panel.
self.t1=wx.TextCtrl(panel)
self.t2=wx.TextCtrl(panel,style=wx.TE_PASSWORD)
self.t3=wx.TextCtrl(panel,size=(200,100),style=wx.TE_MULTILINE)
self.t4 = wx.TextCtrl ( panel, value="ReadOnly Text", style = wx.TE_READONLY |
wx.TE_CENTER )
While the first is a normal text box, the second is a password field. The third one is a
multiline text box and the last text box is non-editable.
EVT_TEXT binder on first box triggers OnKeyTyped() method for each key stroke in it. The
second box is having its MaxLength set to 5. EVT_TEXT_MAXLEN binder sends OnMaxLen()
function running as soon as the user tries to type more than 5 characters. The multiline
text box responds to Enter key pressed because of EVT_TEXT_ENTER binder.
The complete code is as follows:
import wx
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title,size=(350,250))
panel=wx.Panel(self)
vbox=wx.BoxSizer(wx.VERTICAL)
hbox1=wx.BoxSizer(wx.HORIZONTAL)
l1=wx.StaticText(panel, -1, "Text Field")
hbox1.Add(l1, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
self.t1=wx.TextCtrl(panel)
hbox1.Add(self.t1,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
self.t1.Bind(wx.EVT_TEXT,self.OnKeyTyped)
vbox.Add(hbox1)
hbox2=wx.BoxSizer(wx.HORIZONTAL)
48
wxPython
hbox3=wx.BoxSizer(wx.HORIZONTAL)
l3=wx.StaticText(panel, -1, "Multiline Text")
hbox3.Add(l3,1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
self.t3=wx.TextCtrl(panel,size=(200,100),style=wx.TE_MULTILINE)
hbox3.Add(self.t3,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
vbox.Add(hbox3)
self.t3.Bind(wx.EVT_TEXT_ENTER,self.OnEnterPressed)
hbox4=wx.BoxSizer(wx.HORIZONTAL)
l4=wx.StaticText(panel, -1, "Read only text")
hbox4.Add(l4, 1, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
self.t4=wx.TextCtrl(panel, value="ReadOnly
Text",style=wx.TE_READONLY|wx.TE_CENTER)
hbox4.Add(self.t4,1,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL,5)
vbox.Add(hbox4)
panel.SetSizer(vbox)
self.Centre()
self.Show()
self.Fit()
app = wx.App()
Mywin(None,
'TextCtrl demo')
49
wxPython
app.MainLoop()
50
wxPython
A Radio button usually represents one of many selectable buttons available for the user in
a group. Each button, an object of wx.RadioButton class carries a text label next to a round
button.
In order to create a group of mutually selectable buttons, the style parameter of first
wxRadioButton object is set to wx.RB_GROUP. Subsequent button objects are added to a
group.
wxPython API also consists of wx.RadioBox class. Its object offers a border and label to
the group. Buttons in the group can be arranged horizontally or vertically.
wx.RadioButton constructor looks like:
Wx.RadioButton(parent, id, label, pos, size, style)
The style parameter is present only for the first button in the group. Its value is
wx.RB_GROUP. For subsequent buttons in the group, wx.RB_SINGLE style parameter may
be optionally used.
wx.RadioButton event binder wx.EVT_RADIOBUTTON triggers the associated handler
every time any of the buttons in the group is clicked.
Two important methods of wx.RadioButton class are SetValue() to select or deselect a
button programmatically and GetValue() which returns true if a button is selected and
is false otherwise.
A wx.RadioBox places a collection of mutually exclusive buttons in a static box. Each
button in the group takes its label from a List object which acts as choices parameter for
wx.RadioBox constructor.
Buttons in RadioBox are laid out in row-wise or column-wise manner. For that style
parameter
of
constructor
should
be
either
wx.RA_SPECIFY_ROWS
or
wx.RA_SPECIFY_COLS. Number of rows/columns is decided by the value of
majordimensions parameter.
Prototype of wx.RadioBox constructor is:
Wx.RadioBox(parent, id, label, pos, size, choices[], initialdimensions, style)
Following are the important methods in wx.RadioBox class:
GetSelection()
SetSelection()
GetString()
SetString()
Show()
wxPython
Example
The following example demonstrates the use of RadioBox as well as RadioButton. Firstly,
three RadioButtons, grouped by specifying wx.RB_GROUP style are placed on the panel.
self.rb1 = wx.RadioButton(pnl,11, label='Value A', pos=(10,10), style =
wx.RB_GROUP)
self.rb2 = wx.RadioButton(pnl,22, label='Value B',pos=(10,40))
self.rb3 = wx.RadioButton(pnl,33, label='Value C',pos=(10,70))
The RadioBox, on the other hand, reads labels for its buttons from a lblList[] object.
lblList = ['Value X', 'Value Y', 'Value Z']
self.rbox=wx.RadioBox(pnl,label='RadioBox', pos=(80,10), choices=lblList ,
majorDimension=1, style=wx.RA_SPECIFY_ROWS)
Two event binders, one for radio group and other for RadioBox, are declared.
self.Bind(wx.EVT_RADIOBUTTON, self.OnRadiogroup)
self.rbox.Bind(wx.EVT_RADIOBOX,self.onRadioBox)
The corresponding event handlers identify the button selected and display the message
on the console window.
def OnRadiogroup(self, e):
rb = e.GetEventObject()
print rb.GetLabel(),' is clicked from Radio Group'
def onRadioBox(self,e):
print self.rbox.GetStringSelection(),' is clicked from Radio Box'
The complete code is as follows:
import wx
class Example(wx.Frame):
self.InitUI()
52
wxPython
def InitUI(self):
pnl = wx.Panel(self)
self.Centre()
self.Show(True)
ex = wx.App()
Example(None,'RadioButton and RadioBox')
ex.MainLoop()
53
wxPython
54
wxPython
A checkbox displays a small labeled rectangular box. When clicked, a checkmark appears
inside the rectangle to indicate that a choice is made. Checkboxes are preferred over radio
buttons when the user is to be allowed to make more than one choice. In this case, the
third state is called mixed or undetermined state, generally used in doesnt apply
scenario.
Normally, a checkbox object has two states (checked or unchecked). Tristate checkbox
can also be constructed if the appropriate style parameter is given.
wx.CheckBox class constructor takes the following parameters:
Wx.CheckBox(parent, id, label, pos, size, style)
The following style parameter values can be used:
wx.CHK_2STATE
wx.CHK_3STATE
wx.ALIGN_RIGHT
This class has two important methods: GetState() returns true or false depending on if the
checkbox is checked or not. SetValue() is used to select a checkbox programmatically.
wx.EVT_CHECKBOX is the only event binder available. Associated event handler will be
invoked every time any checkbox on the frame is checked or unchecked.
Example
Following is a simple example demonstrating the use of three checkboxes. Handler
function OnChecked() identifies the checkbox, which is responsible for the event and
displays its state.
The complete code is:
import wx
class Example(wx.Frame):
self.InitUI()
55
wxPython
def InitUI(self):
pnl = wx.Panel(self)
ex = wx.App()
Example(None,'CheckBox')
ex.MainLoop()
56
wxPython
wx.CB_DROPDOWN
wx.CB_READONLY
wx.CB_SORT
GetString()
SetString()
SetValue()
GetValue()
FindString()
GetStringSelection()
57
wxPython
wx. EVT_TEXT
wx.
EVT_COMBOBOX_DROPDOWN
wx. EVT_COMBOBOX_CLOSEUP
Parameter n stands for number of strings with which the choice list is to be initialized.
Like comboBox, the list is populated with items in choices[] collection.
For Choice class, only one style parameter is defined. It is wx.CB_SORT. Only one event
binder processes the event emitted by this class. It is wx.EVT_CHOICE.
Example
This example displays the features of wx.ComboBox and wx.Choice. Both objects are put
in a vertical box sizer. The lists are populated with items in languages[] List object.
languages = ['C', 'C++', 'Python', 'Java', 'Perl']
self.combo=wx.ComboBox(panel,choices=languages)
self.choice=wx.Choice(panel,choices=languages)
The following handler functions display the selected item from the list on the label.
def OnCombo(self, event):
self.label.SetLabel("selected "+ self.combo.GetValue() +" from Combobox")
def OnChoice(self,event):
self.label.SetLabel("selected "+ self.choice.GetString(
self.choice.GetSelection() ) +" from Choice")
58
wxPython
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title=title,size=(300,200))
panel=wx.Panel(self)
box=wx.BoxSizer(wx.VERTICAL)
self.label=wx.StaticText(panel,label="Your choice:" ,style=wx.ALIGN_CENTRE)
box.Add(self.label, 0 , wx.EXPAND |wx.ALIGN_CENTER_HORIZONTAL |wx.ALL, 20)
cblbl=wx.StaticText(panel,label="Combo box",style=wx.ALIGN_CENTRE)
box.Add(cblbl,0,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
languages = ['C', 'C++', 'Python', 'Java', 'Perl']
self.combo=wx.ComboBox(panel,choices=languages)
box.Add(self.combo,1,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
chlbl=wx.StaticText(panel,label="Choice control",style=wx.ALIGN_CENTRE)
box.Add(chlbl,0,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
self.choice=wx.Choice(panel,choices=languages)
box.Add(self.choice,1,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
box.AddStretchSpacer()
self.combo.Bind(wx.EVT_COMBOBOX, self.OnCombo)
self.choice.Bind(wx.EVT_CHOICE, self.OnChoice)
panel.SetSizer(box)
self.Centre()
self.Show()
def OnChoice(self,event):
self.label.SetLabel("You selected "+ self.choice.GetString
(self.choice.GetSelection())+" from Choice")
app = wx.App()
Mywin(None,
app.MainLoop()
59
wxPython
60
wxPython
Progressbar control in wxPython is called Gauge. Wx.Gauge class object shows a vertical
or horizontal bar, which graphically shows incrementing quantity. It is typically used to
demonstrate progression of a process like copying files or installing a software.
Wx.Gauge control can be used in determinate as well as indeterminate mode. When the
time required to complete any operation can be fairly accurately determined, the gauge
progress bar shows the percentage of completed task. However, in indeterminate mode,
it only indicates that the process is ongoing.
In determinate mode, the progress position is updated periodically. In indeterminate
mode, calling Pulse() function will update the progress bar.
Parameters required by Wx.Gauge class constructor is:
wx.Gauge(parent, id, range, pos, size, style)
The range parameter sets the maximum value for the gauge. In indeterminate mode, this
parameter is ignored.
The possible style parameters for Gauge class are:
wx.GA_HORIZONTAL
wx.GA_VERTICAL
wx.GA_SMOOTH
wx.GA_TEXT
Some of the important methods of this class are listed in the following table:
GetRange()
SetRange()
GetValue()
SetValue()
Pulse()
61
wxPython
Example
In the following example, a horizontal Gauge object is added in the vertical box sizer of
panel.
self.gauge = wx.Gauge(pnl, range=20, size=(250, 25), style = wx.GA_HORIZONTAL)
There is also a button whose click event is associated with a handler function.
self.btn1 = wx.Button(pnl, label="Start")
self.Bind(wx.EVT_BUTTON, self.OnStart, self.btn1)
The handler function OnStart() updates the progress of gauge after every second.
def OnStart(self, e):
while True:
time.sleep(1);
self.count = self.count + 1
self.gauge.SetValue(self.count)
if self.count>=20:
print "end"
return
def InitUI(self):
self.count = 0
pnl = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
62
wxPython
vbox.Add((0, 30))
vbox.Add(hbox1, flag=wx.ALIGN_CENTRE)
vbox.Add((0, 20))
vbox.Add(hbox2, proportion=1, flag=wx.ALIGN_CENTRE)
pnl.SetSizer(vbox)
self.SetSize((300, 200))
self.Centre()
self.Show(True)
63
wxPython
A slider presents the user with a groove over which a handle can be moved. It is a classic
widget to control a bounded value. Position of the handle on the groove is equivalent to
an integer between the lower and upper bounds of the control.
wxPython API contains wx.Slider class. It offers same functionality as that of Scrollbar.
Slider offers a convenient way to handle dragging the handle by slider specific
wx.EVT_SLIDER event binder.
The definition of wx.Slider constructor takes the following eight parameters:
wx.Slider(parent, id, value, minValue, maxValue, pos, size, style)
Sliders lower and upper values are set by minValue and maxValue parameters. The
starting value is defined by the value parameter.
Many style parameter values are defined. Following are some of them:
wxSL_HORIZONTAL
wxSL_VERTICAL
wxSL_AUTOTICKS
wxSL_LABELS
Horizontal slider
Vertical slider
Displays tickmarks on the slider
Displays the min, max, and current value
wxSL_MIN_MAX_LABELS
wxSL_VALUE_LABEL
GetMax()
GetValue()
SetMin()
SetMax()
SetRange()
SetValue()
SetTick()
SetTickFreq()
64
wxPython
As the slider behaves similar to a scroll bar, the scroll bar event binders can also be used
along with it.
wx.EVT_SCROLL
wx.EVT_SLIDER
Example
In the example that follows, the slider is used to control the size of a label. First of all, a
slider object is placed in a vertical box sizer below which is a StaticText.
self.sld = wx.Slider(pnl, value=10, minValue=1, maxValue=100, style=
wx.SL_HORIZONTAL|wx.SL_LABELS)
class Mywin(wx.Frame):
def InitUI(self):
pnl = wx.Panel(self)
vbox=wx.BoxSizer(wx.VERTICAL)
65
wxPython
66
wxPython
A horizontal bar just below the title bar of a top level window is reserved to display a series
of menus. It is an object of wx.MenuBar class in wxPython API.
An object of wx.Menu class is added to the menu bar. It is also used to create context
menu and popup menu. Each menu may contain one or more wx.MenuItem objects or
cascaded Menu objects.
wx.MenuBar class has a parameterized constructor in addition to a default one.
wx.MenuBar()
Parameter n represents the number of menus. Menu is an array of menus and titles, and
an array of strings. If the style parameter is set to wx.MB_DOCKABLE, the menubar can
be docked.
Following is a list of methods of wx.MenuBar class:
Append()
Check()
Enable()
Remove()
A wx.Menu class object is a pull-down list of one or more menu items, one of which may
be selected by the user.
The following table shows frequently required methods of wx.Menu class:
Append()
AppendMenu()
AppendRadioItem()
AppendCheckItem()
AppendSeparator()
Insert()
InsertRadioItem()
InsertCheckItem()
67
wxPython
InsertSeparator()
Remove()
GetMenuItems()
A Menu Item can be directly added using Append() function, or an object of wx.MenuItem
class is used to append.
wx.Menu.Append(id, text, kind)
In order to define a menu item, the menu in which it is to be added must be mentioned.
wxPython has a large number of standard IDs to be assigned to standard menu items. On
some OS platforms, they are associated with standard icons too.
wx.ID_SEPARATOR
wx.ID_ANY
wx.ID_OPEN
wx.ID_CLOSE
wx.ID_NEW
wx.ID_SAVE
wx.ID_SAVEAS
wx.ID_EDIT
wx.ID_CUT
wx.ID_COPY
wx.ID_PASTE
However, any unique integer number can be assigned as ID. The text parameter is its
caption. Kind parameter takes one of the following enumerators:
wx.ITEM_NORMAL
wx.ITEM_CHECK
wx.ITEM_RADIO
68
wxPython
wx.Menu class also has AppendRadioItem() and AppendCheckItem() that dont require
kind parameter.
A menu Item can be set to display an icon or shortcut. SetBitmap() function of
wx.MenuItem class requires a bitmap object to be displayed.
wx.MenuItem.SetBitmap(wx.Bitmap(image file))
EVT_MENU event binder helps in processing the menu selection.
self.Bind(wx.EVT_MENU, self.menuhandler)
Example
The following example demonstrates most of the above mentioned features of menu
system in wxPython. It shows a File menu displayed in the Menu bar. Normal menu item,
a sub menu, radio items and check items are added into it. Menu items having an icon are
also present.
Event handler, when invoked retrieves ID associated with the event and can be further
processed. For instance, if New menu item is selected, it is echoed in the text box on the
frame.
The complete code is as follows:
import wx
class Mywin(wx.Frame):
def InitUI(self):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
newitem=wx.MenuItem(fileMenu,wx.ID_NEW, text="New",kind=wx.ITEM_NORMAL)
newitem.SetBitmap(wx.Bitmap("new.bmp"))
fileMenu.AppendItem(newitem)
fileMenu.AppendSeparator()
editMenu=wx.Menu()
copyItem=wx.MenuItem(editMenu, 100,text="copy",kind = wx.ITEM_NORMAL)
69
wxPython
copyItem.SetBitmap(wx.Bitmap("copy.bmp"))
editMenu.AppendItem(copyItem)
cutItem=wx.MenuItem(editMenu, 101,text="cut",kind = wx.ITEM_NORMAL)
cutItem.SetBitmap(wx.Bitmap("cut.bmp"))
editMenu.AppendItem(cutItem)
pasteItem=wx.MenuItem(editMenu, 102,text="paste",kind = wx.ITEM_NORMAL)
pasteItem.SetBitmap(wx.Bitmap("paste.bmp"))
editMenu.AppendItem(pasteItem)
fileMenu.AppendMenu(wx.ID_ANY, "Edit",editMenu)
fileMenu.AppendSeparator()
fileMenu.AppendCheckItem(103,"Checkable")
quit = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+Q')
fileMenu.AppendItem(quit)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
self.text=wx.TextCtrl(self,-1, style=wx.EXPAND|wx.TE_MULTILINE)
self.Bind(wx.EVT_MENU, self.menuhandler)
self.SetSize((350, 250))
self.Centre()
self.Show(True)
ex = wx.App()
Mywin(None,'MenuBar demo')
ex.MainLoop()
70
wxPython
71
wxPython
One or more horizontal strips of toolbars comprising of buttons with text caption or icons
are normally placed just below the MenuBar in a top level frame.
If the style parameter of wx.Toolbar object is set to wx.TB_DOCKABLE, it becomes
dockable. A floating toolbar can also be constructed using wxPythons AUIToolBar class.
Constructor without any arguments places a toolbar with default parameters. Additional
parameters can be passed to wx.ToolBar class constructor as follows:
Wx.ToolBar(parent, id, pos, size, style)
Style parameters defined for wx.ToolBar include the following constants:
wx.TB_FLAT
wx.TB_HORIZONTAL
wxTB_VERTICAL
wx.TB_DEFAULT_STYLE
wx.TB_DOCKABLE:
wx.TB_NO_TOOLTIPS:
Doesn't show the short help tooltips for the tools, when
the mouse hovers over them
wx.TB_NOICONS:
wx.TB_TEXT
Tool buttons of different features can be added into the toolbar. Wx.ToolBar class has the
following useful methods:
AddTool()
AddRadioTool()
AddCheckTool()
AddLabelTool()
AddSeparator()
AddControl()
wxPython
ClearTools()
RemoveTool()
Realize()
The parent parameter is the toolbar in which the button is added. Image icon is specified
by bitmap parameter.
The general tool buttons emit EVT_TOOL event. Other controls if added to the toolbar must
be bound by respective CommandEvent binder to the event handler.
Example
In the following example, the toolbar shows two normal tool buttons, three radio tool
buttons and a combobox.
First of all, the toolbar object is activated.
tb = wx.ToolBar( self, -1 )
self.ToolBar = tb
Using AddTool() method, two tools with icons for New and Save are added.
tb.AddTool( 101, wx.Bitmap("new.png") )
tb.AddTool(102,wx.Bitmap("save.png"))
A group of RadioTools is then added to the toolbar, only one of which is selectable at a
time.
right=tb.AddRadioTool(222,wx.Bitmap("right.png"))
center=tb.AddRadioTool(333,wx.Bitmap("center.png"))
justify=tb.AddRadioTool(444,wx.Bitmap("justify.png"))
A wx.ComboBox control is now added to the toolbar using AddControl() method. Combo
box list contains the names of fonts.
self.combo=wx.ComboBox( tb, 555, value="Times", choices =
["Arial","Times","Courier"] )
Realize() method needs to be called in order to finalize the toolbar construction.
tb.Realize()
73
wxPython
Finally, event binders for the toolbar and the combobox are registered.
tb.Bind(wx.EVT_TOOL, self.Onright)
tb.Bind(wx.EVT_COMBOBOX,self.OnCombo)
Respective event handlers append methods process the event source. While EVT_TOOL
events ID is displayed in the text box below the toolbar, the selected font name is added
to it when EVT_COMBOBOX event triggers.
def Onright(self, event):
self.text.AppendText(str(event.GetId())+"\n")
def OnCombo(self,event):
self.text.AppendText( self.combo.GetValue()+"\n")
The entire code is as follows:
import wx
class Mywin(wx.Frame):
def InitUI(self):
menubar = wx.MenuBar()
menu=wx.Menu()
menubar.Append(menu,"File")
self.SetMenuBar(menubar)
tb = wx.ToolBar( self, -1 )
self.ToolBar = tb
right=tb.AddRadioTool(222,wx.Bitmap("right.png"))
center=tb.AddRadioTool(333,wx.Bitmap("center.png"))
justify=tb.AddRadioTool(444,wx.Bitmap("justify.png"))
tb.Bind(wx.EVT_TOOL, self.Onright)
74
wxPython
tb.Bind(wx.EVT_COMBOBOX,self.OnCombo)
self.combo=wx.ComboBox( tb, 555, value= "Times", choices=
["Arial","Times","Courier"])
tb.AddControl(self.combo )
tb.Realize()
self.SetSize((350, 250))
self.text=wx.TextCtrl(self,-1, style=wx.EXPAND|wx.TE_MULTILINE)
self.Centre()
self.Show(True)
def Onright(self, event):
self.text.AppendText(str(event.GetId())+"\n")
def OnCombo(self,event):
self.text.AppendText( self.combo.GetValue()+"\n")
ex = wx.App()
Mywin(None,'ToolBar demo')
ex.MainLoop()
75
wxPython
Although a Dialog class object appears like a Frame, it is normally used as a pop-up
window on top of a parent frame. The objective of a Dialog is to collect some data from
the user and send it to the parent frame. Dialog frame can be modal (where it blocks the
parent frame) or modeless (dialog frame can be bypassed). ShowModal() method displays
dialog frame in the modal manner, while Show() makes it modeless.
wxPython has a number of preconfigured Dialog widgets such as MessageDialog,
FileDialog, FontDialog, etc.
wx.Dialog supports the use of Sizers just as a wx.Frame object. Hence, a custom Dialog
can be designed.
Wx.Dialog class constructor takes the following usual parameters:
wx.Dialog(parent, id, title, pos, size, style)
Default appearance of Dialog widget shows only Close box in the title bar. However, it can
be customized using a combination of the following style parameters:
wx.CAPTION
wx.RESIZE_BORDER
wxSYSTEM_MENU
wx.CLOSE_BOX
wx.MAXIMIZE_BOX
wx.MINIMIZE_BOX
wx.STAY_ON_TOP
wx.DIALOG_NO_PARENT
wx.DEFAULT_DIALOG_STYLE
EVT_INIT_DIALOG
76
wxPython
As mentioned above, the objective of Dialog is to collect data and return to the parent
window. However, some useful methods are available for Dialog class.
DoOK()
ShowModal()
ShowWindowModal()
EndModal()
Shows OK button
wx.CANCEL
wx.YES_NO
wx.YES_DEFAULT
wx.NO_DEFAULT
wx.ICON_EXCLAMATION
wx.ICON_ERROR
wx.ICON_HAND
Same as wx.ICON_ERROR
wx.ICON_INFORMATION
wx.ICON_QUESTION
MessageDialog
This is declared with the following constructor:
wx.MessageDialog(parent, message, caption, style, pos)
One or more lines of the text to be displayed is the message parameter, while the caption
is displayed on the title bar. Default style parameter is wx.OK|wx.ECNRE. Other style
parameters allow the message box to be customized.
wx.MessageBox is a convenience function to construct a message box instead of using
MessageDialog.
77
wxPython
Example
Given below is a simple demonstration of modal and modeless behavior of Dialog. The
parent window is a wx.Frame object with two buttons. Click event on the first button
displays a dialog in modal fashion. Hence, any operation on the parent window is prevented
till the dialog is closed. The second button displays a modeless dialog, which doesnt
obstruct access to parent window. The third button displays a MessageBox.
The entire code is as follows:
import wx
class MyDialog(wx.Dialog):
def __init__(self, parent, title):
super(MyDialog, self).__init__(parent, title=title,size=(250,150))
panel=wx.Panel(self)
self.btn=wx.Button(panel,wx.ID_OK,label="ok",size=(50,20),pos=(75,50))
class Mywin(wx.Frame):
def InitUI(self):
panel=wx.Panel(self)
btn=wx.Button(panel, label="Modal Dialog", pos=(75,10))
btn1=wx.Button(panel, label="Modeless Dialog", pos=(75,40))
btn2=wx.Button(panel, label="MessageBox", pos=(75,70))
btn.Bind(wx.EVT_BUTTON, self.OnModal)
a=btn1.Bind(wx.EVT_BUTTON, self.OnModeless)
print a
btn2.Bind(wx.EVT_BUTTON, self.Onmsgbox)
self.Centre()
self.Show(True)
wxPython
ex = wx.App()
Mywin(None,'MenuBar demo')
ex.MainLoop()
wx.TextEntryDialog
Object of this class displays a dialog with one text field, a customizable label prompting
the user to input and two buttons with predefined styles.
Although this dialog requests a one line input, the text box can be customized by using
TextCtrl styles like password and multiline.
Contents of the text field are collected as return value when the user clicks OK button.
TextEntryDialog constructor is as follows:
wx.TextEntryDialog(parent, id, message, caption, value, style, pos)
The text to be displayed on the Dialog window is passed as the message parameter. The
caption parameter is the string to be displayed in the title bar. Default string in the text
box is the value parameter. TextCtrl in dialog can be configured to display password
characters (wx.TE_PASSWORD) and/or multiline (wx.TE_MULTILINE).
79
wxPython
SetValue()
GetValue()
ShowModal()
Example
Top level frame in the following example shows a button and a read-only TextCtrl widget.
self.text = wx.TextCtrl(pnl, size=(250, 25),style=wx.TE_READONLY)
self.btn1 = wx.Button(pnl, label="Enter Text")
The button responds to click and invokes the OnClick() function.
self.Bind(wx.EVT_BUTTON, self.OnClick, self.btn1)
OnClick() function displays a TextEntryDialog.
dlg = wx.TextEntryDialog(self, 'Enter Your Name','Text Entry Dialog')
Return value of the dialog is fetched by GetValue() function and displayed in the TextCtrl
object of top level frame.
if dlg.ShowModal() == wx.ID_OK:
self.text.SetValue("Name entered:"+dlg.GetValue())
The complete code is as follows:
import wx
class Mywin(wx.Frame):
self.InitUI()
def InitUI(self):
self.count = 0
pnl = wx.Panel(self)
80
wxPython
vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.text = wx.TextCtrl(pnl, size=(250, 25),style=wx.TE_READONLY)
self.btn1 = wx.Button(pnl, label="Enter Text")
self.Bind(wx.EVT_BUTTON, self.OnClick, self.btn1)
hbox1.Add(self.text, proportion=1, flag=wx.ALIGN_CENTRE)
hbox2.Add(self.btn1, proportion=1, flag=wx.RIGHT, border=10)
vbox.Add((0, 30))
vbox.Add(hbox1, flag=wx.ALIGN_CENTRE)
vbox.Add((0, 20))
vbox.Add(hbox2, proportion=1, flag=wx.ALIGN_CENTRE)
pnl.SetSizer(vbox)
self.Centre()
self.Show(True)
ex = wx.App()
Mywin(None,'TextEntry Demo')
ex.MainLoop()
wxPython
wx.FileDialog Class
This class represents a file selector dialog. It enables the user to navigate through the file
system and select a file to open or save. Appearance of the dialog is OS specific.
A file filter can also be applied to display the files of specified extensions only. Starting
directory and default file name can also be set.
FileDialog constructors prototype looks like this:
wx.FileDialog(parent, message, DefaultDir, DefaultFile, wildcard, style, pos,
size)
The message represents text to be displayed. DefaultDir is the initial directory. One or
more types of files can be set as file filter represented by wildcard parameter.
Style parameters defined for FileDialog are:
wx.FD_DEFAULT_STYLE
Equivalent to wxFD_OPEN
wx.FD_OPEN
wx.FD_SAVE
82
wxPython
wx.FD_OVERWRITE_PROMPT
wx.FD_MULTIPLE
wx.FD_CHANGE_DIR:
GetFileName()
GetPath()
SetDirectory()
SetFilename()
SetPath()
ShowModal()
Example
In the following example, the top level frame shows a button and a multiline TextCtrl.
self.text = wx.TextCtrl(pnl, size=(-1,200),style=wx.TE_MULTILINE)
self.btn1 = wx.Button(pnl, label="Open a File")
OnClick() function displays a FileDialog in open mode. Its selection is returned as dlg. The
selected file is obtained by GetPath() function and its contents are displayed in TextCtrl
box on parent window.
def OnClick(self, e):
wildcard="Text Files (*.txt)|*.txt"
dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", wildcard,
wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
83
wxPython
f = open(dlg.GetPath(), 'r')
with f:
data = f.read()
self.text.SetValue(data)
The complete code is as follows:
import wx
import os
class Mywin(wx.Frame):
self.InitUI()
def InitUI(self):
self.count = 0
pnl = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.text = wx.TextCtrl(pnl, size=(-1,200),style=wx.TE_MULTILINE)
self.btn1 = wx.Button(pnl, label="Open a File")
self.Bind(wx.EVT_BUTTON, self.OnClick, self.btn1)
hbox1.Add(self.text, proportion=1, flag=wx.ALIGN_CENTRE)
hbox2.Add(self.btn1, proportion=1, flag=wx.RIGHT, border=10)
vbox.Add(hbox2, proportion=1, flag=wx.ALIGN_CENTRE)
vbox.Add(hbox1, proportion=1,flag=wx.EXPAND|wx.ALIGN_CENTRE)
pnl.SetSizer(vbox)
self.Centre()
self.Show(True)
wxPython
if dlg.ShowModal() == wx.ID_OK:
f = open(dlg.GetPath(), 'r')
with f:
data = f.read()
self.text.SetValue(data)
dlg.Destroy()
ex = wx.App()
Mywin(None,'FileDialog Demo')
ex.MainLoop()
85
wxPython
wx.FontDialog Class
The object of this class is a font chooser dialog. Appearance of this dialog too is OS specific.
Attributes, such as name, size, weight, etc. of the selected font are returned as the return
value of this dialog.
Fontdata parameter required for this class constructor is used to initialize these attributes.
wx.FontDialog(parent, data)
86
wxPython
GetFontData() method of this class contains the parameters of the selected font.
The following code demonstrating the use of FontDialog has a button and a label
(StaticText object).
self.text = wx.StaticText(pnl, label="hello")
self.btn1 = wx.Button(pnl, label="Choose Font")
dlg.Destroy()
self.InitUI()
def InitUI(self):
self.count = 0
pnl = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.text = wx.StaticText(pnl, label="hello")
self.btn1 = wx.Button(pnl, label="Choose Font")
87
wxPython
vbox.Add(hbox1, proportion=1,flag=wx.ALIGN_CENTRE)
pnl.SetSizer(vbox)
self.Centre()
self.Show(True)
dlg.Destroy()
ex = wx.App()
Mywin(None,'FileDialog Demo')
ex.MainLoop()
The above code produces the following output:
88
wxPython
wxPython class library contains various book control. A book control allows the user to
switch between various panels in a frame. This is especially useful when a large amount
of data is to be presented.
Book classes are inherited from wx.BookCtrlBase class. The following type of book
controls are available:
wx.Notebook
wx.Choicebook
wx.Listbook
wx.Treebook
wx.Notebook widget presents a tabbed control. One Notebook object in a frame has one
or more tabs (called Pages), each of them having a panel showing the layout of controls.
The user can switch between pages by clicking on the respective tab title.
Notebook class constructor takes familiar parameters as the following:
wx.Notebook(parent, id, pos, size, style)
The following style parameters are available for customization of the widget:
wx.NB_TOP
wx.NB_LEFT
wx.NB_RIGHT
wx.NB_BOTTOM
wx.NB_FIXEDWIDTH
wx.NB_MULTILINE
89
wxPython
SetSelection()
AddPage()
DeletePage()
InsertPage()
RemovePage()
EVT_NOTEBOOK_PAGE_CHANGING()
Example
The following example deploys a Notebook control in a top level frame.
nb=wx.Notebook(self)
Two classes based on wx.Panel are designed. The first, puts a multi-line TextCtrl in it.
class MyPanel1(wx.Panel):
def __init__(self, parent):
super(MyPanel1, self).__init__(parent)
text=wx.TextCtrl(self,style=wx.TE_MULTILINE,size=(250,150))
90
wxPython
class MyDialog(wx.Dialog):
def __init__(self, parent, title):
super(MyDialog, self).__init__(parent, title=title,size=(250,150))
panel=wx.Panel(self)
self.btn=wx.Button(panel,wx.ID_OK,label="ok",size=(50,20),pos=(75,50))
class Mywin(wx.Frame):
def InitUI(self):
nb=wx.Notebook(self)
nb.AddPage(MyPanel1(nb),"Editor")
nb.AddPage(MyPanel2(nb),"RadioButtons")
self.Centre()
self.Show(True)
class MyPanel1(wx.Panel):
def __init__(self, parent):
super(MyPanel1, self).__init__(parent)
text=wx.TextCtrl(self,style=wx.TE_MULTILINE,size=(250,150))
class MyPanel2(wx.Panel):
def __init__(self, parent):
super(MyPanel2, self).__init__(parent)
lblList = ['Value X', 'Value Y', 'Value Z']
rbox=wx.RadioBox(self, label='RadioBox', pos=(25,10), choices =
lblList,
majorDimension=1, style=wx.RA_SPECIFY_ROWS)
ex = wx.App()
Mywin(None,'NoteBook demo')
ex.MainLoop()
91
wxPython
92
wxPython
in wxWidgets API.
AuiManager manages the panes associated with a particular frame using each panels
information in wx.aui.AuiPanelInfo object. Let us learn about various properties of
PanelInfo object control docking and floating behavior.
Putting dockable windows in the top level frame involves the following steps:
First, create an AuiManager object.
self.mgr = wx.aui.AuiManager(self)
Position: More than one pane can be placed inside a dockable region. Each is given
a position number.
Row: More than one pane appears in one row. Just like more than one toolbar
appearing in the same row.
Using this PanelInfo, the designed panel is added into the manager object.
info1=wx.aui.AuiPaneInfo().Bottom()
self.mgr.AddPane(pnl,info1)
Rest of the top level window may have other controls as usual.
93
wxPython
class Mywin(wx.Frame):
self.mgr = wx.aui.AuiManager(self)
pnl=wx.Panel(self)
pbox=wx.BoxSizer(wx.HORIZONTAL)
text1 = wx.TextCtrl(pnl, -1, "Dockable",style=wx.NO_BORDER | wx.TE_MULTILINE)
pbox.Add(text1, 1, flag=wx.EXPAND)
pnl.SetSizer(pbox)
info1=wx.aui.AuiPaneInfo().Bottom()
self.mgr.AddPane(pnl,info1)
panel=wx.Panel(self)
text2 = wx.TextCtrl(panel,size=(300,200),style= wx.NO_BORDER |
wx.TE_MULTILINE)
box=wx.BoxSizer(wx.HORIZONTAL)
box.Add(text2, 1, flag=wx.EXPAND)
panel.SetSizerAndFit(box)
self.mgr.Update()
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Centre()
self.Show(True)
app = wx.App()
94
wxPython
Mywin(None,"Dock Demo")
app.MainLoop()
95
wxPython
A typical GUI application may have multiple windows. Tabbed and stacked widgets allow
to activate one such window at a time. However, many a times this approach may not be
useful as view of other windows is hidden.
One way to display multiple windows simultaneously is to create them as independent
windows. This is called as SDI (Single Document Interface). This requires more memory
resources as each window may have its own menu system, toolbar, etc.
MDI framework in wxPython provides a wx.MDIParentFrame class. Its object acts as a
container for multiple child windows, each an object of wx.MDIChildFrame class.
Child windows reside in the MDIClientWindow area of the parent frame. As soon as a child
frame is added, the menu bar of the parent frame shows a Window menu containing
buttons to arrange the children in a cascaded or tiled manner.
Example
The following example illustrates the uses of MDIParentFrame as top level window. A Menu
button called NewWindow adds a child window in the client area. Multiple windows can be
added and then arranged in a cascaded or tiled order.
The complete code is as follows:
import wx
class MDIFrame(wx.MDIParentFrame):
def __init__(self):
wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size=(600,400))
menu = wx.Menu()
menu.Append(5000, "&New Window")
menu.Append(5001, "E&xit")
menubar = wx.MenuBar()
menubar.Append(menu, "&File")
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnNewWindow, id=5000)
self.Bind(wx.EVT_MENU, self.OnExit, id=5001)
wxPython
win.Show(True)
app = wx.App()
frame = MDIFrame()
frame.Show()
app.MainLoop()
Parent frame
Cascaded
Tiled horizontally
Tiled vertically
97
wxPython
Object of this class is a layout manager, which holds two subwindows whose size can be
changed dynamically by dragging the boundaries between them. The Splitter control
gives a handle that can be dragged to resize the controls.
wx.SplitterWindow class has a very basic constructor with all parameters having usual
default values.
wx.SplitterWindow(self, id, pos, size, style)
wxSP_3DSASH
wxSP_BORDER
wxSP_NOBORDER
wxSP_PERMIT_UNSPLIT
No border (default)
Always allow to unsplit, even with the minimum pane size
other than zero
EVT_SPLITTER_SASH_POS_CHANGED()
EVT_SPLITTER_UNSPLIT()
EVT_SPLITTER_DCLICK()
The following code demonstrates the functioning of SplitterWindow. The splitter object is
added to the top level frame.
splitter = wx.SplitterWindow(self, -1)
98
wxPython
The splitter object is vertically split and two panels are added to two subwindows. The
width of subwindows can be resized with the help of sash.
splitter.SplitVertically(panel2, panel1)
import wx
class Mywin(wx.Frame):
wxPython
ex = wx.App()
Mywin(None,'Splitter Demo')
ex.MainLoop()
100
wxPython
GDI+ (Graphics Drawing Interface), CoreGraphics and Cairo libraries form the
framework of drawing API in wxPython. wx.GraphicsContext is the primary drawable
object, using which various Device Context objects are created.
wx.DC is an abstract class. Its derived classes are used to render graphics and text on
different devices. The Device Context classes are:
wx.ClientDC - Use this to paint on the client area of the window (the part without
borders and other decorations), but do not use it from within an wxPaintEvent.
wx.PaintDC - Use this to paint on the client area of the window, but only from
within a wxPaintEvent.
wx.WindowDC - Use this to paint on the whole area of the window, including
decorations. This may not be available on non-Windows platforms.
Drawing API of wxPython offers different functions for drawing shape, text and image.
Objects required for drawing purpose, like Colour, Pen, Brush and Font can also be
constructed using GDI classes.
wx.Colour Class
Colour object represents combination of RGB (RED, Green and Blue) intensity values, each
on the scale of 0-255. There are a few predefined colour objects like:
wxBLACK
wxBLUE
wxCYAN
wxGREEN
wxYELLOW
wxLIGHT_GREY
wxRED
wxWHITE
101
wxPython
wx.Pen Class
Pen object determines the colour, width and style of the shape of graphics like line,
rectangle, circle etc.
Predefined Pen objects are:
wxBLACK_DASHED_PEN
wxBLACK_PEN
wxBLUE_PEN
wxCYAN_PEN
wxGREEN_PEN
wxYELLOW_PEN
wxGREY_PEN
wxLIGHT_GREY_PEN
wxMEDIUM_GREY_PEN
wxRED_PEN
wxTRANSPARENT_PEN
wxWHITE_PEN
wx.SOLID
wx.DOT
wx.LONG_DASH
wx.SHORT_DASH
wx.DOT_DASH
wx.TRANSPARENT
wx.Brush Class
Brush is another elementary graphics object required to fill the backgrounds of shapes
such as rectangle, ellipse, circle etc.
A custom Brush object requires wx.Colour and Brush style parameters. The following is a
list of predefined brush styles:
wx.SOLID
wx.STIPPLE
wx.BDIAGONAL_HATCH
wx.CROSSDIAG_HATCH
wx.FDIAGONAL_HATCH
wx.CROSS_HATCH
wx.HORIZONTAL_HATCH
102
wxPython
wx.VERTICAL_HATCH
wx.TRANSPARENT
wxPython has a number of functions that facilitate drawing different shapes, text and
image.
DrawRectangle()
DrawCircle()
DrawEllipse()
DrawLine()
DrawBitmap()
DrawText()
Example
The above functions are implemented in the following example, making use of Pen, Brush,
Colour and Font objects.
The complete code is as follows:
import wx
class Mywin(wx.Frame):
def InitUI(self):
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Centre()
self.Show(True)
def OnPaint(self, e):
dc = wx.PaintDC(self)
brush = wx.Brush("white")
dc.SetBackground(brush)
dc.Clear()
dc.DrawBitmap(wx.Bitmap("python.jpg"),10,10,True)
color=wx.Colour(255,0,0)
103
wxPython
b=wx.Brush(color)
dc.SetBrush(b)
dc.DrawCircle(300,125,50)
dc.SetBrush(wx.Brush(wx.Colour(255,255,255)))
dc.DrawCircle(300,125,30)
font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
dc.SetFont(font)
dc.DrawText("Hello wxPython",200,10)
pen=wx.Pen(wx.Colour(0,0,255))
dc.SetPen(pen)
dc.DrawLine(200,50,350,50)
dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH))
dc.DrawRectangle(380, 15, 90, 60)
ex = wx.App()
Mywin(None,'Drawing demo')
ex.MainLoop()
The above code produces the following output:
104
wxPython
wxHTML library contains classes for parsing and displaying HTML content. Although this is
not intended to be a full-featured browser, wx.HtmlWindow object is a generic HTML
viewer.
HtmlWindow class constructor takes a familiar look:
(Parent, id, pos, size, style)
wxHW_SCROLLBAR_AUTO
wxHW_NO_SELECTION
105
wxPython
The following code displays a simple HTML browser. On running the code, a TextEntry
Dialog pops up asking a URL to be entered. LoadPage() method of wx.HtmlWindow class
displays the contents in the window.
import
wx
import
wx.html
class MyHtmlFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(600,400))
html = wx.html.HtmlWindow(self)
if "gtk2" in wx.PlatformInfo:
html.SetStandardFonts()
dlg = wx.TextEntryDialog(self, 'Enter a URL','HTMLWindow')
if dlg.ShowModal() == wx.ID_OK:
html.LoadPage(dlg.GetValue())
app = wx.App()
frm = MyHtmlFrame(None, "Simple HTML Browser")
frm.Show()
app.MainLoop()
106
wxPython
A wx.ListBox widget presents a vertically scrollable list of strings. By default, a single item
in the list is selectable. However, it can be customized to be multi-select.
ListCtrl widget is a highly enhanced list display and selection tool. List of more than one
column can be displayed in Report view, List view or Icon view.
ListBox constructor has the following definition:
Wx.ListBox(parent, id, pos, size, choices, style)
Choices parameter is the list of strings used to populate the list.
wx.ListBox object is customizable with the following style parameters:
wxLB_SINGLE
Single-selection list
wxLB_MULTIPLE
wxLB_EXTENDED
wxLB_HSCROLL
wxLB_ALWAYS_SB
wxLB_NEEDED_SB
wxLB_SORT
IsSorted()
GetString()
SetString()
EVT_LISTBOX binder triggers the handler when an item in the list is selected or when the
selection changes programmatically. Handler function bound by EVT_LISTBOX_DCLICK is
invoked when a double-click event on the list box item occurs.
107
wxPython
Example
In the following example, a ListBox control and a TextCtrl object are respectively placed
in the left and the right portion of a horizontal box sizer. ListBox is populated with strings
in languages[] list object.
languages = ['C', 'C++', 'Java', 'Python', 'Perl',
'JavaScript','PHP','VB.NET','C#']
self.text=wx.TextCtrl(panel,style=wx.TE_MULTILINE)
lst = wx.ListBox(panel, size=(100,-1), choices= languages, style=wx.LB_SINGLE)
Two objects are placed in a horizontal box sizer.
box=wx.BoxSizer(wx.HORIZONTAL)
box.Add(lst,0,wx.EXPAND)
box.Add(self.text, 1, wx.EXPAND)
ListBox control is linked to onListBox() handler with EVT_LISTBOX binder.
self.Bind(wx.EVT_LISTBOX, self.onListBox, lst)
The handler appends selected string into multiline TextCtrl on the right.
def onListBox(self, event):
self.text.AppendText( "Current selection: "+
event.GetEventObject().GetStringSelection() + "\n")
The complete code is as follows:
import wx
class Mywin(wx.Frame):
panel=wx.Panel(self)
box=wx.BoxSizer(wx.HORIZONTAL)
self.text=wx.TextCtrl(panel,style=wx.TE_MULTILINE)
108
wxPython
box.Add(lst,0,wx.EXPAND)
box.Add(self.text, 1, wx.EXPAND)
panel.SetSizer(box)
panel.Fit()
self.Centre()
self.Bind(wx.EVT_LISTBOX, self.onListBox, lst)
self.Show(True)
def onListBox(self, event):
self.text.AppendText( "Current selection:
"+event.GetEventObject().GetStringSelection()+"\n")
ex = wx.App()
Mywin(None,'ListBox Demo')
ex.MainLoop()
wx.ListCtrl is an enhanced, and therefore, more complex widget. Where a ListBox shows
only one column, ListCtrl can contain multiple columns. The appearance of ListCtrl widget
is controlled by the following style parameters:
wx.LC_LIST
wx.LC_REPORT
wxPython
wxLC_REPORT
wx.LC_ICON
wx.LC_SMALL_ICON
wx.LC_ALIGN_LEFT
wx.LC_EDIT_LABELS
wx.LC_NO_HEADER
wx.LC_SORT_ASCENDING
wx.LC_SORT_DESCENDING
wx.LC_HRULES
wx.LC_VRULES
Example
A ListCtrl widget in report view is constructed in the following example.
self.list = wx.ListCtrl(panel, -1, style=wx.LC_REPORT)
Header columns are created by InsertColumn() method which takes the column number,
caption, style and width parameters.
self.list.InsertColumn(0, 'name', width=100)
self.list.InsertColumn(1, 'runs', wx.LIST_FORMAT_RIGHT, 100)
self.list.InsertColumn(2, 'wkts', wx.LIST_FORMAT_RIGHT, 100)
A list of tuples, each containg three strings, called players[] stores the data which is used
to populate columns of the ListCtrl object.
New row starts with InsertStringItem() method which returns the index of the current row.
Use of sys.maxint gives the row number after the last row. Using the index, other columns
are filled by SetStringItem() method.
for i in players:
index = self.list.InsertStringItem(sys.maxint, i[0])
self.list.SetStringItem(index, 1, i[1])
self.list.SetStringItem(index, 2, i[2])
110
wxPython
panel=wx.Panel(self)
box=wx.BoxSizer(wx.HORIZONTAL)
for i in players:
index = self.list.InsertStringItem(sys.maxint, i[0])
self.list.SetStringItem(index, 1, i[1])
self.list.SetStringItem(index, 2, i[2])
box.Add(self.list,1,wx.EXPAND)
panel.SetSizer(box)
panel.Fit()
self.Centre()
self.Show(True)
ex = wx.App()
Mywin(None,'ListCtrl Demo')
ex.MainLoop()
The above code produces the following output. Players data is displayed in report view:
111
wxPython
112
wxPython
Provision of drag and drop is very intuitive for the user. It is found in many desktop
applications where the user can copy or move objects from one window to another just by
dragging it with the mouse and dropping on another window.
Drag and drop operation involves the following steps:
Create wx.DropSource
wx.TextDropTarget
wx.FileDropTarget
Many wxPython widgets support drag and drop activity. Source control must have dragging
enabled, whereas target control must be in a position to accept (or reject) drag.
Source Data that the user is dragging is placed on the the target object. OnDropText() of
target object consumes the data. If so desired, data from the source object can be deleted.
Example
In the following example, two ListCrl objects are placed horizontally in a Box Sizer. List on
the left is populated with a languages[] data. It is designated as the source of drag. One
on the right is the target.
languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP',
'VB.NET','C#']
self.lst1 = wx.ListCtrl(panel, -1, style=wx.LC_LIST)
self.lst2 = wx.ListCtrl(panel, -1, style=wx.LC_LIST)
for lang in languages:
self.lst1.InsertStringItem(0,lang)
The second list control is empty and is an argument for object of TextDropTarget class.
class MyTextDropTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
113
wxPython
class MyTarget(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
class Mywin(wx.Frame):
panel=wx.Panel(self)
box=wx.BoxSizer(wx.HORIZONTAL)
wxPython
dt = MyTarget(self.lst2)
self.lst2.SetDropTarget(dt)
wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
box.Add(self.lst1,0,wx.EXPAND)
box.Add(self.lst2, 1, wx.EXPAND)
panel.SetSizer(box)
panel.Fit()
self.Centre()
self.Show(True)
ex = wx.App()
Mywin(None,'Drag&Drop Demo')
ex.MainLoop()
The above code produces the following output:
115