Reputation: 338
I tried all sort of options but no success in implement simple scrollbar for two or more listboxes. Following is my code giving error while scrolling. I hope you guys are helping me...
scrollbar .scroll -orient v
pack .scroll -side left -fill y
listbox .lis1
pack .lis1 -side left
listbox .lis2
pack .lis2 -side left
for {set x 0} {$x < 100} {incr x} {
.lis1 insert end $x
.lis2 insert end $x
}
.lis1 configure -yscrollcommand [list .scroll set]
.lis2 configure -yscrollcommand [list .scroll set]
.scroll configure -command ".lis1 yview .lis2 yview ";
thanking you.
Upvotes: 1
Views: 2558
Reputation: 11
I know that this post is really old but I recently discovered what I think is a fairly simple solution. Instead of using the vertical scrollbar I found that I can use the slider widget. With the slider you can get the position of the slider and use that to set the yview of the listbox(es). Multiple listboxes can be scrolled simultaneously. I use vtcl to build the GUI so the code I can provide may not beimmediately obvious for those using tk wm comands. But here is the code I use. It is bound to slider motion.
set listIndex [$widget(Scale1) get]
$widget(Listbox1) yview $listIndex
$widget(Listbox2) yview $listIndex
Hope that is helpful to somebody.
Upvotes: 1
Reputation: 137567
There are a number of examples on the Tcler's wiki, but the core principle is to use a procedure to ensure that the scrolling protocol is synchronized between the widgets. Here's an example based off that wiki page:
# Some data to scroll through
set ::items [lrepeat 10 {*}"The quick brown fox jumps over the lazy dog."]
# Some widgets that will scroll together
listbox .list1 -listvar ::items -yscrollcommand {setScroll .scroll}
listbox .list2 -listvar ::items -yscrollcommand {setScroll .scroll}
scrollbar .scroll -orient vertical -command {synchScroll {.list1 .list2} yview}
# The connectors
proc setScroll {s args} {
$s set {*}$args
{*}[$s cget -command] moveto [lindex [$s get] 0]
}
proc synchScroll {widgets args} {
foreach w $widgets {$w {*}$args}
}
# Put the GUI together
pack .list1 .scroll .list2 -side left -fill y
It's worth noting that you can also plug any other scrollable widget into this scheme; everything in Tk scrolls the same way (except with -xscrollcommand
and xview
for horizontal scrolling, together with a change of scrollbar orientation). Furthermore, the connectors here, unlike the ones on the wiki page, can be used with multiple groups of scrolled widgets at once; the knowledge of what is scrolled together is stored in the -command
option of the scrollbar (first argument to synchScroll
callback).
[EDIT]: For 8.4 and before, you need slightly different connector procedures:
# The connectors
proc setScroll {s args} {
eval [list $s set] $args
eval [$s cget -command] [list moveto [lindex [$s get] 0]]
}
proc synchScroll {widgets args} {
foreach w $widgets {eval [list $w] $args}
}
Everything else will be the same.
Upvotes: 1
Reputation: 33203
If you plan to do much work in the the callback command - make a procedure to do it as that is both faster (the procedure gets byte compiled) and less likely to introduce tcl syntax problems. In this case you are trying to perform two tcl commands in the scrollbar function so you need to separate the statements using newline or a semicolon.
Calling the scrollbar set function from both listboxes will just have the second one override the first. You either need a function to merge those two or if the lists have the same lengths, just call it from one of them to set the scrollbar size and position and then update all listboxes with the scrollbar callback.
There is a multilistbox package somewhere - try the Tcl wiki to locate examples.
Upvotes: 0