English 中文(简体)
wxPython - Quick Guide
  • 时间:2024-09-17

wxPython - Quick Guide


Previous Page Next Page  

wxPython - Introduction

wxPython is a Python wrapper for wxWidgets (which is written in C++), a popular cross-platform GUI toolkit. Developed by Robin Dunn along with Harri Pasanen, wxPython is implemented as a Python extension module.

Just pke 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 apppcation 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 pke 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, maintainabipty, and extensibipty. The project began in 2012 and is still in beta stage.

wxPython - Environment

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.

wxPython - Hello World

A simple GUI apppcation displaying Hello World message is built using the following steps −

    Import wx module.

    Define an object of Apppcation class.

    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.

    Activate the frame window by show() method.

    Enter the main event loop of Apppcation object.

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 −

Hello World

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 pke menu bar, toolbar and status bar can be enabled. A wxFrame window can contain any frame that is not a dialog or another frame.

wxPython - GUI Builder Tools

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

wxFormBuilder is an open source, cross-platform WYSIWYG GUI builder that can translate the wxWidget GUI design into C++, Python, PHP or XML format. A brief introduction to usage of wxFormBuilder is given here.

First of all the latest version of wxFormBuilder needs to be downloaded and installed from http://sourceforge.net/projects/wxformbuilder/. On opening the apppcation, a new project with blank grey area at the center appears.

Give a suitable name to the project and choose Python as code generation language. This is done in the Object properties window as shown in the following image −

Object Properties

Then from ‘Forms’ tab of components palette, choose Frame.

Choose Frame

Add a vertical wxBoxSizer from ‘Layouts’ tab.

Add wxBoxSizer

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 pke the following image −

Add Controls

Enable Expand and Stretch on these three controls. In the object properties for wxButton object, assign a function findsquare() to OnButtonCpck event.

Three Controls

Save the project and press F8 to generate Python code for developed GUI. Let the generated file be named as Demo.py

In the executable Python script, import demo.py and define FindSquare() function. Declare Apppcation object and start a main event loop. Following is the executable code −

import wx 
  
#import the newly created GUI file 
import demo  
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 apppcations 
app.MainLoop() 

The above code produces the following output −

GUI Builder Output

wxPython - Major Classes

Original wxWidgets (written in C++) is a huge class pbrary. GUI classes from this pbrary are ported to Python with wxPython module, which tries to mirror the original wxWidgets pbrary 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 apppcation itself. After generating the GUI, apppcation enters in an event loop by MainLoop() method. Following diagrams depict the class hierarchy of most commonly used GUI classes included in wxPython.

wxWindow Hierarchy wxGDIObject Hierarchy wxSizer Hierarchy wxButton Hierarchy
S.N. Classes & Description
1 wx.Frame

wx.Frame Class has a default constructor with no arguments.

2 wx.Panel

wx.Panel class is usually put inside a wxFrame object. This class is also inherited from wxWindow class.

3 wx.StaticText

wx.StaticText class object presents a control holding such read-only text. It can be termed as a passive control since it doesn’t produce any event.

4 TextCtrl

In wxPython, an object of wx.TextCtrl class serves this purpose. It is a control in which the text can be displayed and edited.

5 RadioButton & RadioBox

Each button, an object of wx.RadioButton class carries a text label next to a round button. wxPython API also consists of wx.RadioBox class. Its object offers a border and label to the group.

6 wx.CheckBox

A checkbox displays a small labeled rectangular box. When cpcked, a checkmark appears inside the rectangle to indicate that a choice is made.

7 ComboBox & Choice Class

A wx.ComboBox object presents a pst of items to select from. It can be configured to be a dropdown pst or with permanent display. wxPython API contains a wx.Choice class, whose object is also a dropdown pst, which is permanently read-only.

8 Wx.Gauge

Wx.Gauge class object shows a vertical or horizontal bar, which graphically shows incrementing quantity.

9 wx.Spder

wxPython API contains wx.Spder class. It offers same functionapty as that of Scrollbar. Spder offers a convenient way to handle dragging the handle by spder specific wx.EVT_SLIDER event binder.

10 wx.MenuBar

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.

11 wx.Toolbar

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 wxPython’s AUIToolBar class.

12 Wx.Dialog

Although a Dialog class object appears pke 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.

13 wx.Notebook

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.

14 wx.SpptterWindow

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 Spptter control gives a handle that can be dragged to resize the controls.

15 HTMLWindow

wxHTML pbrary 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.

16 ListBox & ListCtrl

A wx.ListBox widget presents a vertically scrollable pst of strings. By default, a single item in the pst is selectable. ListCtrl widget is a highly enhanced pst display and selection tool. List of more than one column can be displayed in Report view, List view or Icon view.

wxPython - Event Handpng

Unpke a console mode apppcation, which is executed in a sequential manner, a GUI based apppcation is event driven. Functions or methods are executed in response to user’s actions pke cpcking a button, selecting an item from collection or mouse cpck, etc., called events.

Data pertaining to an event which takes place during the apppcation’s 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, cpck 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 OnCpck() method of the program on a button’s cpck event, the following statement is required −

self.b1.Bind(EVT_BUTTON, OnCpck)

Bind() method is inherited by all display objects from wx.EvtHandler class. EVT_.BUTTON here is the binder, which associates button cpck event to OnCpck() 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 __init__(self, *args, **kw): 
      super(Example, self).__init__(*args, **kw)  
      self.InitUI() 
           
   def InitUI(self): 
      self.Bind(wx.EVT_MOVE, self.OnMove) 
      self.SetSize((250, 180)) 
      self.SetTitle( Move event ) 
      self.Centre() 
      self.Show(True)
		   
   def OnMove(self, e): 
      x, y = e.GetPosition() 
      print "current window position x = ",x," y= ",y 
         
ex = wx.App() 
Example(None) 
ex.MainLoop()   

The above code produces the following output −

Move Event

current window position x = 562 y = 309

current window position x = 562 y = 309

current window position x = 326 y = 304

current window position x = 384 y = 240

current window position x = 173 y = 408

current window position x = 226 y = 30

current window position x = 481 y = 80

Some of the subclasses inherited from wx.Event are psted in the following table −

S.N. Events & Description
1

wxKeyEvent

Occurs when a key is presses or released

2

wxPaintEvent

Is generated whenever contents of the window needs to be redrawn

3

wxMouseEvent

Contains data about any event due to mouse activity pke mouse button pressed or dragged

4

wxScrollEvent

Associated with scrollable controls pke wxScrollbar and wxSpder

5

wxCommandEvent

Contains event data originating from many widgets such as button, dialogs, cppboard, etc.

6

wxMenuEvent

Different menu-related events excluding menu command button cpck

7

wxColourPickerEvent

wxColourPickerCtrl generated events

8

wxDirFilePickerEvent

Events generated by FileDialog and DirDialog

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 __init__(self, parent): 
      super(MyPanel, self).__init__(parent)
		
      b = wx.Button(self, label =  Btn , pos = (100,100)) 
      b.Bind(wx.EVT_BUTTON, self.btnclk) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonCpcked) 
		
   def OnButtonCpcked(self, e): 
         
      print  Panel received cpck event. propagated to Frame class  
      e.Skip()  
		
   def btnclk(self,e): 
      print "Button received cpck event. propagated to Panel class" 
      e.Skip()
		
class Example(wx.Frame):

   def __init__(self,parent): 
      super(Example, self).__init__(parent)  
         
      self.InitUI() 

   def InitUI(self):
	
      mpnl = MyPanel(self) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonCpcked)
		
      self.SetTitle( Event propagation demo ) 
      self.Centre() 
      self.Show(True)
		
   def OnButtonCpcked(self, e): 
         
      print  cpck event received by frame class  
      e.Skip()
		
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 cpck generates a CommandEvent which can be propagated to its parent by Skip() method.

MyPanel class object also binds the received event to another handler OnButtonCpcked(). This function in turn transmits to its parent, the Example class. The above code produces the following output −

Event Handpng Output

Button received cpck event. Propagated to Panel class. 
Panel received cpck event. Propagated to Frame class. 
Cpck event received by frame class.

wxPython - Layout Management

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 −

    Widgets inside the window are automatically resized.

    Ensures uniform appearance on display devices with different resolutions.

    Adding or removing widgets dynamically is possible without having to redesign.

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.

S.N. Sizers & Description
1 BoxSizer

This sizer allows the controls to be arranged in row-wise or column-wise manner. BoxSizer’s layout is determined by its orientation argument (either wxVERTICAL or wxHORIZONTAL).

2 GridSizer

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.

3 FlexiGridSizer

This sizer also has a two dimensional grid. However, it provides pttle more flexibipty in laying out the controls in the cells.

4 GridBagSizer

GridBagSizer is a versatile sizer. It offers more enhancements than FlexiGridSizer. Child widget can be added to a specific cell within the grid.

5 StaticBoxSizer

A StaticBoxSizer puts a box sizer into a static box. It provides a border around the box along with a label at the top.

wxPython - Buttons

Button widget is most widely used in any GUI interface. It captures the cpck event generated by the user. Its most obvious use is to trigger a handler function bound to it.

wxPython class pbrary 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 −

S.N. Methods & Description
1

SetLabel()

Sets the button’s caption programmatically

2

GetLabel()

Returns the button’s caption

3

SetDefault()

Button is set to default for the top level window. Emulates the cpck event on pressing Enter key

Two important methods of wx.ToggleButton class are −

S.N. Methods & Description
1

GetValue()

Returns the state of toggle button (on/off)

2

SetValue()

Sets the state of button programmatically

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)

Some of the predefined bitmap type constants are −

wx.BITMAP_TYPE_BMP
wx.BITMAP_TYPE_ICO
wx.BITMAP_TYPE_CUR
wx.BITMAP_TYPE_TIFF
wx.BITMAP_TYPE_TIF
wx.BITMAP_TYPE_GIF
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 handpng.

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, "cpck Me")

Toggle button is constructed by following statement −

self.tbtn = wx.ToggleButton(panel , -1, "cpck to on")

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.OnCpcked) 
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)

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))
  
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
  
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))

Cpck event of these three buttons is directed to OnCpcked() method.

self.bmpbtn.Bind(wx.EVT_BUTTON, self.OnCpcked) 
self.bmpbtn1.Bind(wx.EVT_BUTTON, self.OnCpcked) 
self.bmpbtn2.Bind(wx.EVT_BUTTON, self.OnCpcked)

Internal labels of these buttons are set to NEW, OPEN and SAVE respectively.

OnCpcked() event handler function retrieves the label of source button, which caused the cpck event. That label is printed on the console.

def OnCpcked(self, event): 
   btn = event.GetEventObject().GetLabel() 
   print "Label of pressed button = ",btn 

OnToggle() event handler is triggered when the toggle button is cpcked. Its state is read by GetValue() method and accordingly, the button’s caption is set.

def OnToggle(self,event): 
   state = event.GetEventObject().GetValue() 
   if state == True: 
      print "off" 
      event.GetEventObject().SetLabel("cpck to off") 
   else: 
      print "on" 
      event.GetEventObject().SetLabel("cpck to on")

The complete code psting is as follows −

import wx 
class Mywin(wx.Frame): 
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (200,150))  
      panel = wx.Panel(self) 
      vbox = wx.BoxSizer(wx.VERTICAL) 
         
      self.btn = wx.Button(panel,-1,"cpck Me") 
      vbox.Add(self.btn,0,wx.ALIGN_CENTER) 
      self.btn.Bind(wx.EVT_BUTTON,self.OnCpcked) 
         
      self.tbtn = wx.ToggleButton(panel , -1, "cpck to on") 
      vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER) 
      self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle) 
         
      hbox = wx.BoxSizer(wx.HORIZONTAL) 
         
      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)) 
			
      hbox.Add(self.bmpbtn,0,wx.ALIGN_CENTER) 
      self.bmpbtn.Bind(wx.EVT_BUTTON,self.OnCpcked) 
      self.bmpbtn.SetLabel("NEW") 
         
      bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) 
			
      hbox.Add(self.bmpbtn1,0,wx.ALIGN_CENTER) 
      self.bmpbtn1.Bind(wx.EVT_BUTTON,self.OnCpcked) 
      self.bmpbtn1.SetLabel("OPEN") 
         
      bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
			
      hbox.Add(self.bmpbtn2,0,wx.ALIGN_CENTER) 
      self.bmpbtn2.Bind(wx.EVT_BUTTON,self.OnCpcked)
      self.bmpbtn2.SetLabel("SAVE") 
         
      vbox.Add(hbox,1,wx.ALIGN_CENTER) 
      panel.SetSizer(vbox) 
        
      self.Centre() 
      self.Show() 
      self.Fit()  
		
   def OnCpcked(self, event): 
      btn = event.GetEventObject().GetLabel() 
      print "Label of pressed button = ",btn 
		
   def OnToggle(self,event): 
      state = event.GetEventObject().GetValue() 
		
      if state == True: 
         print "Toggle button state off" 
         event.GetEventObject().SetLabel("cpck to off") 
      else: 
         print " Toggle button state on" 
         event.GetEventObject().SetLabel("cpck to on") 
             
app = wx.App() 
Mywin(None,   Button demo ) 
app.MainLoop()

The above code produces the following output −

Buttons Output

Label of pressed button = cpck Me

Toggle button state off

Toggle button state on

Label of pressed button = NEW

Label of pressed button = OPEN

Label of pressed button = SAVE

wxPython - Dockable Windows

wxAui is an Advanced User Interface pbrary incorporated in wxWidgets API. Wx.aui.AuiManager the central class in AUI framework.

AuiManager manages the panes associated with a particular frame using each panel’s 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)

Then, a panel with required controls is designed.

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)

The following parameters of AuiPanelInfo are set.

    Direction − Top, Bottom, Left, Right, or Center

    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 pke more than one toolbar appearing in the same row.

    Layer − Panes can be placed in layers.

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.

The complete code is as follows −

import wx 
import wx.aui
  
class Mywin(wx.Frame):
  
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title, size = (300,300)) 
		
      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) 
		
   def OnClose(self, event): 
      self.mgr.UnInit() 
      self.Destroy() 
		
app = wx.App()
Mywin(None,"Dock Demo")  
app.MainLoop()

The above code produces the following output −

Dock Demo

wxPython - Multiple Document Interface

A typical GUI apppcation 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 MDICpentWindow 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 cpent 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, "&Exit") 
      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) 
		
   def OnExit(self, evt): 
      self.Close(True)  
		
   def OnNewWindow(self, evt): 
      win = wx.MDIChildFrame(self, -1, "Child Window")
      win.Show(True) 
		
app = wx.App() 
frame = MDIFrame() 
frame.Show() 
app.MainLoop()

The above code produces the following output −

MDI output

wxPython - Drawing API

GDI+ (Graphics Drawing Interface), CoreGraphics and Cairo pbraries 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.ScreenDC − Use this to paint on the screen, as opposed to an inspanidual window.

    wx.CpentDC − Use this to paint on the cpent 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 cpent 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, pke 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 pke −

    wxBLACK

    wxBLUE

    wxCYAN

    wxGREEN

    wxYELLOW

    wxLIGHT_GREY

    wxRED

    wxWHITE

Color with custom combination of RGB values is formed as wx.Colour object.

wx.Colour(r,g,b)

wx.Pen Class

Pen object determines the colour, width and style of the shape of graphics pke pne, 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

Predefined Pen styles are −

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, elppse, circle etc.

A custom Brush object requires wx.Colour and Brush style parameters. The following is a pst of predefined brush styles −

wx.SOLID
wx.STIPPLE
wx.BDIAGONAL_HATCH
wx.CROSSDIAG_HATCH
wx.FDIAGONAL_HATCH
wx.CROSS_HATCH
wx.HORIZONTAL_HATCH
wx.VERTICAL_HATCH
wx.TRANSPARENT

wxPython has a number of functions that faciptate drawing different shapes, text and image.

S.N. Functions & Description
1

DrawRectangle()

Draws a rectangle of given dimensions

2

DrawCircle()

Draws a circle at the given point as center and radius

3

DrawElppse()

Draws an elppse with the given x and y radius

4

DrawLine()

Draws a pne beween two wx.Point objects

5

DrawBitmap()

Draw an image at the given position

6

DrawText()

Displays the given text at the specified position

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 __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (500,300))  
      self.InitUI() 
         
   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)
      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 −

Drawing Demo

wxPython - Drag & Drop

Provision of drag and drop is very intuitive for the user. It is found in many desktop apppcations 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 −

    Declare a drop target

    Create data object

    Create wx.DropSource

    Execute drag operation

    Cancel or accept drop

In wxPython, there are two predefined drop targets −

    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 pst 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
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)

OnDropText() method adds source data in the target pst control.

Drag operation is initiapzed by the event binder.

wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)

OnDragInit() function puts drag data on the target and deletes from the source.

def OnDragInit(self, event): 
   text = self.lst1.GetItemText(event.GetIndex()) 
   tobj = wx.PyTextDataObject(text) 
   src = wx.DropSource(self.lst1) 
   src.SetData(tobj) 
   src.DoDragDrop(True) 
   self.lst1.DeleteItem(event.GetIndex())

The complete code is as follows −

import wx
  
class MyTarget(wx.TextDropTarget): 
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object  
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)  
		
class Mywin(wx.Frame): 
            
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (-1,300))   
      panel = wx.Panel(self) 
      box = wx.BoxSizer(wx.HORIZONTAL)  
      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) 
             
      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)  
     
   def OnDragInit(self, event): 
      text = self.lst1.GetItemText(event.GetIndex()) 
      tobj = wx.PyTextDataObject(text) 
      src = wx.DropSource(self.lst1) 
      src.SetData(tobj) 
      src.DoDragDrop(True) 
      self.lst1.DeleteItem(event.GetIndex()) 
		
ex = wx.App() 
Mywin(None, Drag&Drop Demo ) 
ex.MainLoop()

The above code produces the following output −

Drag Drop Output Advertisements