Version 26 of Wizard

Updated 2011-05-13 13:40:52 by RLE

A wizard is an interactive help utility that guides the user through a potentially complex task, such as configuring a PPP driver to work with a new modem. Wizards are often implemented as a sequence of dialog boxes which the user can move forwards and backwards through, filling in the details required. The implication is that the expertise of a human wizard in one of the above senses is encapsulated in the software wizard, allowing the average user to perform expertly.


Tcl Software for creating Wizard functionality

 What: TkWizard
 Where: http://www2.clearlight.com/~oakley/tcl/tkwizard/
 Description: tkwizard is a megawidget for creating wizards. It is
  written in pure tcl and runs on any version of tcl/tk from 8.0 onward.
  Included with the distribution is a wizard for building wizards. While
  not a full fledged wizard IDE, it is sufficient to create the initial
  framework for a wizard. Plus it serves a dual purpose as an example of
  a simple wizard. I hope to add additional wizards when I release the
  final 1.0 product some day.
 Version: 1.0a1
 Author: Bryan Oakley
 Updated: 2003/08/03

(Bryan Oakley 04-Aug-2003: I'm a bit embarrassed that I've let that project go without an update for almost two years. But, truth be told, in that two years I've only had perhaps a half-dozen comments, so it seems there's not a whole lot of interest. If interest picks up I'll take the time to make my latest changes available. So, the project isn't dead, I just haven't felt motivated to complete the docs and update the examples to work with the latest bits).

MGS [2003/08/04] - Well, I created this page because I was surprised to find one didn't exist. I started writing a package installer application, which then turned into a wizard, and so I started looking at TkWizard. I would certainly be interested in seeing whatever changes have been made since version 1.0a1. I am actually quite interested in incorporating some kind of wizard into my eWidgets Toolkit, whether it's based upon TkWizard, or whether I rip the guts out of my package installer. I think I may be trying to do more than what TkWizard is capable of, but then I may just be guilty of not fully reading and understanding the docs. Maybe some better examples could help?

schlenk [2003/08/07] - TkWizard is nice, but a bit unfinished in some respects (so the alpha is quite appropriate). Some better examples and some more work on layout control/images would be really great. (As would usage of msgcat).

SC [2005/02/22] -- snitwiz is my own wizard package based on snit.


MJ For a very basic wizard which leaves the creation of the separate pages up to you but will provide the navigation, the following can serve as a start:

 package require Tk
 # requires 8.5 because of use of {*}
 package require Tcl 8.5

 proc wizard {toplevel pages} {
    toplevel $toplevel
    set page_list {}

    for {set i 1} {$i <= $pages} {incr i} {
        set finish {}
        set page $toplevel.p$i
        frame $page
        frame $page.page
        lappend page_list $page.page
        button $page.p -text Previous... -command [list move $page.page -1]
        button $page.n -text Next... -command [list move $page.page 1]
        if {$i == 1} {
            $page.p configure -state disabled
        }
        if {$i == $pages} {
            $page.n configure -state disabled
            button $page.f -text Finish -command $toplevel.finish           
            set finish $page.f
        }
        grid $page.page  -columnspan 4  -sticky nsew
        grid $page.p $page.n {*}$finish
        grid columnconfigure $page 3 -weight 1
        grid rowconfigure $page 0 -weight 1
    }
    return $page_list
 }



 proc move {page {offset 0}} {
    set page [winfo parent $page]
    regexp {^(.*\.p)([0-9]+)$} $page -> root number
    pack forget $page
    set newnumber [expr {$number + $offset}]
    set newpage "$root$newnumber"       et}]
    pack $newpage -fill both -expand 1
    wm title [winfo toplevel $newpage] "Page $newnumber"
 }

 set pages [wizard .wzrd 10]

 # finish button will call <toplevel>.finish
 proc .wzrd.finish {args} {
    # wzrd is finished
    puts "finished"
    destroy .wzrd
 }

 # set up pages
 # every page returned by [wizard ...] is a frame where you can construct your page
 foreach page $pages {
    text $page.t
    pack $page.t -fill both -expand 1
 }

 # show the first page
 move [lindex $pages 0]
 wm withdraw .
 catch {console show} 

VS [2007/10/29] Also using BWidget::PagesManager.

add wizard


HaO 2010-10-19: Thank you, Brian, for TkWizard. I use it now since the start. Here are some experiences:

  • Quite clever design, not much resorces needed
  • The namespace and the window path are related. This makes it internally quick but has the drawback, that each call to a procedure of the contained module have to use full qualified namespaces. This is specially ugly, if msgcat is used:
$this stepconfigure -title [namespace eval ::select "mc infoOptionsTitle"]\
        -subtitle [namespace eval ::select "mc infoOptionsSupp"]\
        -pretext [namespace eval ::select "mc infoOptionsPre"]\
        -posttext [namespace eval ::select "mc infoOptionsPost"]
  • The bind mechanism for the Next and Finish buttons are one for all pages. Often, I want to have a procedure called when a page is finised (by next or finish) to transmit the values. I use this code:
bind .parserawwiz <<WizNextStep>> {[%W namespace]::NextDo %W}
bind .parserawwiz <<WizFinish>> {[%W namespace]::FinalizeDo %W}
# Next dispatcher
.parserawwiz eval {
    proc NextDo {this} {
        set Step [$this cget -step]
        if {0 != [llength [info commands NextDo_$Step]] } {
            if { ! [NextDo_$Step $this]} {
                return -code break
            }
        }
    }
    #...
    # Page save function
    proc NextDo_Regexp {this} {
        return [RegexpTest]
    }
    proc FinalizeDo {this} {
        if {[catch {NextDo $this} Err dErr]} {
            dict unset dErr -level
            return -options $dErr
        }
        # save wizard changes
    }
}
  • No syntax highlighting with Kommodo of the wizard code. Kommodo does not know, that there is code behind .parserawwiz eval and treats it as an argument.
  • Long time ago, I have sent an msg-catted version of the wizard to Brian. He answered, that he will release a new version anyway, which never happened.
  • One pitfall of the current implementation is that the same frame is reused for the client area of all pages. Only all client widgets are destroyed. If the widgets on the last page were managed by the grid manager, eventual row and column settings may propage from one page to the next. One may reset all settings after a page changing using gridClear from grid forget:
set c [$this widget clientArea]
gridClear $c

WJG (21/10/10) The gnocl::assistant widget provides full wizard functionality. Check out the wiki page for more details.