Version 6 of scrollbar

Updated 2002-11-22 20:23:39

Martin Lemburg - 02.09.2002: one question - what can I do to limit a vertical scrollbar to the height of a listbox with the height 1 or 2? The scrollbar is always 3 listbox entries high!

"you want to pack your vertical Scrollbars -fill y and your horizontal Scrollbars -fill x ..."

See also Scroll bars that appear only when needed

GPS customizes scrollbars. He shares at least three somewhere on his site ...

On news:comp.lang.tcl , Ken Jones writes:

In your example, you created the Text and Scrollbar widgets, but you didn't wire them up to each other. Scrollbars have a -command which they call whenever the user interacts with them. Scrollable widgets also have -xscrollcommand and -yscrollcommand options so that they can communicate with their attached Scrollbars (for example, so the Scrollbar knows how large to make the "elevator" and where to place it in the trough).

An example of hooking up a vertical Scrollbar:

 text .t -yscrollcommand {.sbar set}
 scrollbar .sbar -orient vertical -command {.t yview}

An example of hooking up a horizontal Scrollbar

 text .t -xscrollcommand {.sbar set}
 scrollbar .sbar -orient horizontal -command {.t xview}

All scrollable widgets (Canvas, Entry, Listbox, Text) in Tk use the same mechanism. (Although scrolling Canvas widgets is trickier. If you need to scroll a Canvas, check out the Canvas's -scrollregion option as well.)

Also, it looks as though you need to study the pack command more. It's a bit difficult to describe concisely how it works. Here's my best shot at the fundamentals of packing:

  • Tcl lays out widgets in the order you pack them.
  • Each widget is allocated "packing space" (sometimes called a "parcel") in the space that's left over from packing previous widgets, which is called the "cavity."
  • A widget is allocated the entire side of the cavity, as specified by its pack -side option (default is top).
  • The parcel is just wide enough to accommodate the widget when

packing -side left or -side right, or just tall enough to accommodate it when packing -side top or -side bottom.

  • If a widget is smaller than its allocated packing space, pack centers the widget inside of its packing space by default.
  • After packing all the widgets, Tcl "shrink-wraps" the top-level window as tightly as it can around the widgets, squeezing out all the excess space it can.

You can then modify the behavior of the packer through various options like -fill and -anchor, but I'll let you investigate those on your own. But when it comes to Scrollbars, you want to pack your vertical Scrollbars -fill y and your horizontal Scrollbars -fill x, other wise they'll appear in their default size, which is almost never the behavior you want.

So, putting it all together in your example (vertical scrolling):

 text .xstdin -yscrollcommand {.s set}

 # I'm not sure what you meant to do with this next line.
 # For the sake of illustration, I'm assuming that you
 # just wanted to display the output of some cat
 # command in your Text widget. There are better
 # ways of doing this, but that's another topic.

 .xstdin insert 1.0 [exec cat somefile]

 scrollbar .s -orient vertical -command {.xstdin yview}
 button .b1 -text Exit -command exit

 # .b1 gets the entire bottom of the window.
 pack .b1 -side bottom

 # Pack .s next, so that if the user decreases the size
  # of the window, the Text widget shrinks instead of
  # the Scrollbar. .s gets the right-hand side of the space
 # left over. It fills it vertically.
 pack .s -side right -fill y

 # Pack .xstdin last. Expand its packing space into
 # any additional space that becomes available if the
 # user resizes the window. Have the Text widget
 # completely fill its packing space.
 pack .xstdin -expand yes -fill both

 # Sleep 5 minutes (300,000 milliseconds) then close window
 after 900000 exit

 # No need to use tkwait to explicitly enter the
 # event loop. wish enters the event loop automatically
 # at the bottom of the script.

escargo 22 Nov 2002 - As near as I can tell, there is no way to control the size of the elevator for the scrollbar. If I want to use a scrollbar to control a widget that tries to minimize the number items that might appear in the graphical part (keeping the rest in a nongraphical structure), it would be desirable to control the elevator size to reflect the total amount of data accessible and not just the portion residing in the graphical part currently. (See Mass-widget.)

I am going to eventually need a tree control that may need to show thousands of entries. Rather than try to show all of them in the tree control, I might want to keep only a couple of pages of them and build the others when needed. I would want the elevator to reflect the virtual size of the tree and not the current size.

Is there any way to do that?

I can see wanting to configure mapping functions and callbacks to the scrollbar so that it could manage a segmented data set, but the hooks do not appear to be there right now. It slickly handles the case where everything is in the scrollable object, but no support for virtualization.

Tk syntax help - Arts and crafts of Tcl-Tk programming - Category Command