Version 17 of Wizard

Updated 2010-10-19 15:00:02 by oehhar

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} {
                variable wizData
                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} {
                variable wizData
                set Class $wizData(Class)
                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.