Advanced Search
Mail us
Home    Manuel    Links    Faq    Submit a tcl/tk Reference    Contact Us

    Some examples tcl/tk codes     Man of Bwidget     Man of blt     mkwidget screenshots     TkOgl     Video Demo real.


  How can I scroll multiple listboxes with one scrollbar?
 
 Scrollbars have a `-command` option which is used to tell scrollable
widgets (e.g. `listbox`, `text`, `entry`) how to position themselves
when the scrollbar is moved.  This command typically looks like:

scrollbar .scroll -command {.scrollable_widget yview}

where `xview` can substitute for `yview`.  Before the command is
executed, however, it will have two numbers concatenated to it.  The
numbers are fractional positions which indicate how the scrollable
widget should position itself.  Thus, to have a single scrollbar control
multiple widgets, simply use a procedure as the scroll command, and have
that procedure scroll as many widgets as you would like.  The procedure
should take a two arguments (i.e. the fractional positions).  The
following example will connect multiple listboxes to one scrollbar and
correctly handle button bindings in each for single/browse selection:

set BOXES [list .lb0 .lb1 .lb2 .lb3]

proc LBset args {
    global BOXES
    foreach lb $BOXES { eval $lb $args }
}

proc LBselect {sellist} {
    global BOXES
    foreach lb $BOXES {
	$lb selection clear 0 end
	foreach item $sellist {
	    $lb selection set $item
	}
    }
}

proc LBscroll args {
    eval .sy set $args
    LBset yview moveto [lindex $args 0]
}

scrollbar .sy -orient v -command [list LBset yview]
pack .sy -fill y -side right

foreach lb $BOXES {
    if {[info tclversion] == 8.0} {
	listbox $lb -exportselection no -selectmode browse -yscrollcommand LBscroll
	pack $lb -side left -fill both -expand 1

	bind $lb  {
	    LBset selection clear 0 end
	    LBset selection set [%W nearest %y]
	}
	bind $lb  {
	    LBset selection clear 0 end
	    LBset selection set [%W nearest %y]
	    LBset see [%W nearest %y]
	}
	bind $lb  {
	    LBset selection clear 0 end
	    LBset selection set [%W nearest %y]
	}
    } else {
	## As of Tcl 8.1, we have a <> virtual event
	## that we can trigger on - much easier
	## This works just fine with any -selectmode
	listbox $lb -exportselection no -selectmode browse -yscrollcommand LBscroll
	pack $lb -side left -fill both -expand 1

	bind $lb <> {
	    LBselect [%W curselection]
	}
    }
}

for {set i 100} {$i} {incr i -1} {LBset insert end $i}

To get proper behavior with the keys as well, you will have to shadow
the bindings for key movement found in "$tk_library/listbox.tcl".