Version 4 of Getting started with BWidget

Updated 2006-07-12 22:39:07

A BWidget is a megawidget written in pure Tcl/Tk. See the BWidget page for a listing of all available widgets. BWidget is a part of the ActiveTCL Tcl/Tk distribution from ActiveState and it is available as a package for most popular linux distributions. Because BWidget is pure Tcl/Tk, it is also possible to manually install BWidget in a location where it can be found by the auto_path or you can manually extend the auto_path to include the location where BWidget is installed.

Checking if BWidget is installed by starting a tclsh interactive session on unix:

 $> tclsh
 % package require BWidget
 1.7

If the result is

 can't find package BWidget

then most likely BWidget is not installed or the auto_path is not properly set.

Checking auto_path:

 % set auto_path
 /usr/lib/tcl8.4 /usr/lib /usr/lib/tcllib1.6 /usr/lib/tk8.4

If BWidget must be manually installed because of lack of write permission to these directories, let's say in $HOME/local/lib/tcl/bwidget-1.7.0:

 % lappend auto_path $env(HOME)/local/lib/tcl
 /usr/lib/tcl8.4 /usr/lib /usr/lib/tcllib1.6 /usr/lib/tk8.4 /home/n00b3/local/lib/tcl
 % package require BWidget
 1.7

The package management system in tcl do not care that the directory where BWidget resides is called bwidget-1.7.0. The important thing is the pkgIndex file inside the bwidget-1.7.0 directory, but pkgIndex is out of scope for now. Because Tcl does not care much about the name of the directory, it is possible to have more versions of BWidget located in the /home/n00b3/local/lib/tcl directory. This way it is possible to fetch a new version from the web, put it in a local directory, set the auto_path and then start using BWidget.

There are many BWidgets and one of the first one would like to use is maybe the BWidget::Tree because core Tk does not provide a tree widget. Many types of browsers use a tree to show hierarchical relations.

From now on BWidget must be successfuly loaded with the package require BWidget command. Cut and paste into a tclsh interactive session or in tkcon

Creating a small tree:

 package require BWidget
 Tree .t ;# Because of the way BWidget is written it is not BWidget::Tree
 pack .t
 .t insert end root   fruit      -text fruit
 .t insert end fruit  apple      -text apple
 .t insert end fruit  orange     -text orange
 .t insert end fruit  peach      -text peach
 .t insert end fruit  grape      -text grape 
 .t insert end root   cake       -text cake
 .t insert end cake   cheese     -text cheese
 .t insert end cake   cream      -text cream
 .t insert end cake   strawberry -text strawberry
 .t insert end root   drinks     -text drinks
 .t insert end drinks coffee     -text coffee
 .t insert end drinks tea        -text tea
 .t insert end drinks beer       -text beer
 .t insert end drinks water      -text water

As in most other tree widget implementations clicking on the '+' before the node opens the node, and pressing the '-' closes the node. If all tree nodes are visible, some of the nodes dissapear underneath the window. Resizing the window would be one option, but so far the size of the tree widget will stay the same. A better way is to use another BWidget called BWidget::ScrolledWindow. A ScrolledWindow will apply scrollbars horizontally and vertically when needed:

 package require BWidget
 ScrolledWindow .sw
 pack .sw
 Tree .sw.t
 pack .sw.t
 .sw setwidget .sw.t   ;# Make ScrolledWindow manage the Tree widget
 update                ;# Process all UI events before moving on.

 .sw.t insert end root   fruit      -text fruit
 .sw.t insert end fruit  apple      -text apple
 .sw.t insert end fruit  orange     -text orange
 .sw.t insert end fruit  peach      -text peach
 .sw.t insert end fruit  grape      -text grape 
 .sw.t insert end root   cake       -text cake
 .sw.t insert end cake   cheese     -text cheese
 .sw.t insert end cake   cream      -text cream
 .sw.t insert end cake   strawberry -text strawberry
 .sw.t insert end root   drinks     -text drinks
 .sw.t insert end drinks coffee     -text coffee
 .sw.t insert end drinks tea        -text tea
 .sw.t insert end drinks beer       -text beer
 .sw.t insert end drinks water      -text water

If the

 update

above is not included, then an annoying vertical scrollbar is visible, at least on my machine. The update force Tk to process all remaining events in drawing the user interface before moving on.

It is possible to bind actions to a tree:

 proc node_puts {args} {
     puts $args
 }
 .sw.t bindText <1> +node_puts

The '+' in front of node_puts is important in any Tk event binding as it cause the node_puts procedure to be added to processes already bound to a widget. If it is not included (try it out) the selection background will not move as other nodes are clicked.

The procedure node_puts is just printing the name of the node selected in the tree to stdout. When the script is called by the core, the name of the node selected is appended to the script bound to the action <1> which is a Button-1 event. This is a common way to create callbacks in Tk.


Category Widget, part of the BWidget package/extension