Version 17 of How can I make effective use of the BWidgets toolset

Updated 2004-06-28 22:55:13

Purpose: to provide a community updatable web page demonstrating uses for the BWidget toolset, enhancing the docs, pointing to tutorials, etc.


Can anyone discuss the various cross platform issues relating directly to BWidgets? For instance, when I try the demo on a Mac using a Tclkit version of Tcl and Tk, I find a number of errors when trying to test the progress indicator, the -armcommand, the french and german language dialog boxes, the select color dialog box, etc.


What additional documentation is needed for BWidgets?

What new widgets have you written based on the BWidgets toolkit? Is the source available for re-use?


BWidget Examples

The BWidget documentation could really benefit from a few examples, illustrating some of the details.

Paned Window

    package require BWidget

    set pw [PanedWindow .topframe -side bottom]
    for {set i 0} {$i<5} {incr i} {
        set p [$pw add -minsize 100]
        set t [text $p.text]
        pack $t
    }
    pack $pw
    pack .topframe

ScrollableFrame and ScrolledWindow

AM (24 june 2004) To create a scrollable frame, that is, a window that can be moved via scrollbars, use code like:

   #
   # Add a scrollable frame, so that we do not have to worry about the size
   #
   set sw  [ScrolledWindow $tabwin.sw -relief sunken -borderwidth 2]
   set sff [ScrollableFrame $tabwin.sw.f]
   $sw setwidget $sff

   set sf  [$sff getframe]
   #
   # Add the various elements
   #
   set lid [label  $sf.name -text "Name"] 
   set eid [entry $sf.editname -textvariable name]

   pack $sw -fill both -expand yes
   #  do not pack $sff
   pack $lid $eid

(So the trick is: first create a scrolled window, then create a scrollable frame inside it and have it managed by that scrolled window. This extra level is required, because a frame has no xscroll/yscroll subcommand.)

KJN (2004-06-26) added pack statements. Note that the scrollable frame itself should not be packed. The command "$sw setwidget $sff" tells the scrolled window to do geometry management of the scrollable frame. Packing the scrollable frame is unnecessary and will lead to an error.


2003-03-13, Svenn Bjerkem: Tried this example with ActiveTcL 8.4.0.1 and got following error:

 bad option "identify": must be cget or configure
    while executing
 "$w identify $x $y"
    (procedure "::tk::panedwindow::Motion" line 3)
    invoked from within
 "::tk::panedwindow::Motion . 102 2 "
    (command bound to event)

checked the documentation for tk builtins for tk and found that the widget panedwindow has the command identify. For some reason I want to use BWidget, but use the builtin. How come?

AK: AFAIK this could be a confusion in the bindings. I.e. both Tk's panedwindow and Bwidgets panedwindow using the same class name. This causes the Bwidgets panedwindow to get the bindings for Tk's panedwindow, which do not work. I thought we had a bug report about this in Tk or Bwidgets, but can't seem to find it. Or maybe it was something on c.l.t.


Recently, George Petasis answered the following question on comp.lang.tcl:

What can I do to make native Tk widgets and BWidgets look closer, when using them on Linux?

George answered:

 option add *highlightBackground [. cget -background]

(this will make your white borders the same colour as the rest of the window...)

If you want to remove completely these "frames", simply use:

 option add *highlightThickness 0

To use the icons provided with BWidget, you can either

 set im [image create photo -file [file join ::BWIDGET::LIBRARY images folder.gif]]

But it's much easier to use the undocumented (but used in BWidget Demo)

 set im [Bitmap::get folder]

Thanks to de for pointing this out!


Example of how to do Menus

Every one of my scripts that uses BWidgets starts out by defining the mainframe for the application via the MainFrame bwidget. This widget simplifies the construction of the top level for your application by providing a place to easily define pull down menus. It also permits a simple "indicator" area at the bottom which contains any text you want. I often put the program name and version number.

Here is an example directly from a recent application I built to track my hours on various projects. Note how easy it is to build the menu as a string and pass it to the widget construction command. Hot keys are defined by placing the ampersand before the critical hot key character. One of the fields (I've forgotten which one) can be a variable name. If the variable is zero then the entry is greyed out. Handy for doing things like turning off "Save" if nothing has changed yet. I also try to make the "-command" arguments a simple function call with no arguments if possible. That way the commands can be used by other parts of the application when necessary (particularly useful for save and open file operations.) Also built in is a little bit of "help" feed back. The text "New Hours Database" (in the "&New" menu item) will be displayed at the bottom of the Mainframe when the user mouses over the entry. Cheap but effective documentation which requires a tiny bit of effort to create.

 set menudesc {
    "&File" all file 0 {
        {command "&New"           {} "New Hours Database" {} -command file_new}
        {command "&Open"          {} "Open existing hours database" {} -command file_open}
        {command "&Save"          {} "Save to hours database" {} -command file_save}
        {command "Save &As"       {} "Save hours database to new file" {} -command file_save_as}
        {command "Show &Console"  {} "Show TCL console" {} -command {console show}}
        {command "&Hide Console"  {} "Hide TCL console" {} -command {console hide}}
        {command "&Quit"          {} "Quit hours.tcl" {} -command { file_quit}}
    }
    "&Edit" all edit 0 {
        {command "&Copy"  {} "Copy" {} -command {console show;puts "Copy not active"}}
        {command "C&ut"   {} "Cut" {} -command {console show;puts "Cut not active"}}
        {command "&Paste" {} "Paste" {} -command {console show;puts "Paste not active"}}
    }
    "&Interval" all event 0 {
        {command "&New" {} "Begin new interval" {} -command interval_new}
        {command "&Edit" {} "Edit selected interval" {} -command interval_edit}
    }
    "&Report" all report 0 { 
        {command "&Mon-Sun Timecard" {} "Prepare Monday through Sunday Timecard" {} -command report_pti_timecard}
        {command "&Hours"    {} "Prepare total hours report" {} -command report_hours }
        {command "&Full"     {} "Prepare Full report of hours plus journal entries" {} -command report_full}
        {command "&Weekly"   {} "Prepare weekly summary" {} -command report_weekly }
        {command "&Journal"  {} "Prepare Journal report in HTML format" {} -command report_journal}
    }
    "I&nvoice" all invoice 0 {
        {command "&Mark" {} "Mark selected intervals as invoiced" {} -command invoice_mark}
    }
    "&Help" all help 0 {
        {command "&Info" {} "Program Information" {} -command help_info}
        {command "&About" {} "About the Program" {} -command help_about}
    }
 }

 set state(mainframe) [MainFrame .mainframe -menu $menudesc -textvariable state(status)]
 pack $state(mainframe) -fill both -expand yes
 $state(mainframe) addindicator -text "Hours.tcl Rev $state(rev)"

 set mf [$state(mainframe) getframe]; # Place where application widgets get stuffed.

See Enhancing BWidget for more BWidget help.

See also A vertical-tab notebook - Windows Registry Browser - Multi-column display in text widget - Beveled lines - Creating a BWidget Widget


Category GUI