Creating Wizards for wmPython using wxGlade

wxGlade is a great tool for visual development of wxPython GUIs, but (at time of writing this page), is missing some vital features, such as support for wizards.

This page provides an easy recipe for using wxGlade to build the required panels of a wizard, then using a simple wizard subclass to build these panels into the wizard.

Process Overview

The basic steps in this recipe are:

  1. Create a dummy frame in wxGlade, consisting of a notebook which is populated with panels (each panel being a page to be added to our final wizard)
  2. Instantiate a wx.Wizard subclass (code provided below) to create a wizard
  3. Populate this wizard with the pages from the notebook we created in wxGlade

Creating Wizard Pages in wxGlade

Presently, wxGlade has no support for wizards, but it does support notebooks.

We will create a notebook within a dummy frame, and populate it with two or more pages, where each page will ultimately end up in our wizard.

Start up wxGlade, and follow these steps:

  1. Starting out 1.1. Create a new frame 1.2. Within the sizer that wxGlade automatically adds, insert a Notebook 1.3. Within the design window, you should see a single notebook tab
  2. Adding pages 2.1. Click on the notebook within the wxglade 'tree' window 2.2. Click on the 'widget' tab in the wxglade 'properties' window 2.3. Using the 'add' button, create as many tabs as you need, one for each page you want in your wizard 2.4. For each tab you create, choose a name which is a legal python identifier, and is meaningful for the page 2.5. Populate the body of each notebook pane with the widgets you need. 2.6. Click on the 'apply' button when done
  3. Creating panel classes 3.1. For each tab you have just created:
    • 3.1.1. Click on that tab in the design window 3.1.2. Click on the body of the pane 3.1.3. Within the 'properties' window:
      • 3.1.3.1. Click on the 'common' tab 3.1.3.2. Change the 'name' to the python identifier you chose

        3.1.3.3. Change the 'class' from 'wxPanel' to a legal and meaningful python class identifier such as 'MyWizard_page1'

  4. Generate the code
    • 4.1. Save the wxglade file 4.2. Generate python code (ctrl-g)
  5. Add the wizard subclass to your code:

   1 class GladeWizard(wx.wizard.Wizard):
   2     """
   3     Wizard that can be built up from panel classes
   4     generated by wxGlade
   5     """
   6     def __init__(self, parent, id=-1,
   7                 title=wx.EmptyString,
   8                 bitmap=wx.NullBitmap,
   9                 *args, **kw):
  10     
  11         wx.wizard.Wizard.__init__(self, parent, id, title, bitmap, *args, **kw)
  12         self.prevPanel = None
  13 
  14     def addPages(self, pages):
  15         """
  16         Builds this wizard up from a set of panel classes generated
  17         by wxGlade
  18         
  19         Args:
  20             - pages - a sequence of (name, cls) tuples, specifying each
  21               page of the wizard. 
  22               
  23               Each 'name' in the tuple is the attribute under which the corresponding
  24               page of the wizard will be stored in this wizard object as an attribute.
  25               
  26               Each 'cls' in the tuple is a Panel subclass, as generated by wxGlade
  27     
  28         Wizard creation recipe:
  29             1. create a dummy frame in wxglade
  30             2. insert a notebook into that frame's sizer
  31             3. for each desired page of the wizard,
  32                insert a pane into the notebook, and give it a unique class name
  33             4. instantiate this wizard class, then call this method
  34                with a list of (name, panelClass) tuples
  35         """
  36         for name, pageClass in pageClasses:
  37             self.addPage(name, pageClass)
  38         return
  39     
  40     def addPage(self, attrname, panelClass):
  41         """
  42         Adds a panel to this wizard
  43         
  44         Arguments:
  45             - attrname - attribute under which to save a ref to the
  46               instantiated panel within the wizard abject
  47             - panelClass - a subclass of wx.Panel, to add to the new
  48               page of the wizard
  49         """
  50         # create wizard page object, and add on
  51         # instance of our panel class to it
  52         page = wx.wizard.WizardPageSimple(self)
  53         page.sizer = wx.BoxSizer(wx.VERTICAL)
  54         page.SetSizer(page.sizer)
  55         pageInst = panelClass(page)
  56         page.sizer.Add(pageInst, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
  57     
  58         # save the panel instance as named attribute
  59         setattr(self, attrname, pageInst)
  60     
  61         # chain to previous, if this is not the first page
  62         if self.prevPanel:
  63             wx.wizard.WizardPageSimple_Chain(self.prevPanel, page)
  64         else:
  65             self.firstPanel = page
  66     
  67         # remember this as 'previous' page, for adding/chaining the next
  68         self.prevPanel = page
  69     
  70     def run(self):
  71         return self.RunWizard(self.firstPanel)

Creating and using the wizard in your program

Assuming you have set wxglade to generate its python code in 'mygui.py', add to your python program the line:

   1 import mygui as gui

Within your wxApp code, possibly within your .OnInit() method, use code such as:

   1     wizard = self.wizard = GladeWizard(
   2         parent=self.frame,
   3         title="my wizard",
   4         )
   5     wizard.buildFromPanels(
   6         [("pane1", gui.WizardPane_1),
   7          ("pane2", gui.WizardPane_2),
   8          ],
   9         )

If you have a bitmap, you could add it via a 'bitmap=' keyword to the GladeWizard constructor.

With the example above:

   1   self.maxRetries = int(self.wizard.pane1.fld_maxRetries.GetValue())

Conclusion

This is a hack, and will hopefully be obsolete soon (when the wxGlade developers add wizard support).

While it might seem cumbersome, it's probably not much more complicated than it will be when full wizard support is finally added.

WizardFromWxGlade (last edited 2008-03-11 10:50:24 by localhost)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.