[Fabricio Rocha] - 10 Feb 2011 - Scrollable [frame]s which can hold more widgets than the available space could hold are an old desire of many Tclers. There are some ready-to-use solutions like [BWidget] [ScrolledFrame]. But I had read that [canvas] was often used for this task, and became pretty curious about how could this work, specially with [scrollbar]s that would appear or disappear as needed. I posted a question about this in [comp.lang.tcl] but some hours later I got myself a working solution. As I wanted not a ready solution but the logic behind it, some other people might be also interested, so here is an attempt to explain it: 1) The first thing is to create a base frame and, on it, a canvas and its scrollbar(s). Make sure that the canvas can be shrinked or expanded when the same happens to the base frame (for example, with ''-sticky news'' option and [grid columnconfigure]'s ''-weight'' for the canvas column. Then create the "inner frame" and put it inside the canvas with the command ''$canvas'' '''create window'''. This command returns a handler (actually, an "itemID") which must be stored in a namespaced or global variable. 2) The canvas, as other scrollable widgets, supports the ''-yscrollcommand'' and ''-xscrollcommand'' configuration options. These options allow you to define procedures to be called when the visible area changes in the widget. Usually these procedures are the ''$scrollbar'' '''set''' commands for each respective scrollbar, but these options allow other procedures to be called -- for example, one that will verify if the scrollbars are really needed, before calling the necessary $scrollbar set command. Interception, overloading, call it as you want... 3) Create the proc which will add verification to the scrollbars. The command defined for ''-yscrollcommand'' or ''-xscrollcommand'' receives as argument a list of two fractional numbers which tell how much of the widget's contents is currently shown in its window and its axis. If the first one is 0 and the second one is 1, it means that all the contents are visible, so the scrollbar can be hidden (by '''[grid] remove''', for example); otherwise they can be placed back by the geometry manager and have their ''set'' command called. 4) Put the widgets as you want in the inner frame, ensure they are gridded or packed to be expanded or reduced, but know that the frame itself will be probably shrinked to wrap the widgets, and this might leave some blank space visible inside the canvas when it is resized -- specially if, for example, you want the inner frame to be scrolled in only one direction, while its widgets should grow or shrink in the other axis. For avoiding this, after adding the widgets to the inner frame, you should call a proc which will update its size. Why a proc? Because the same operation must be done when the canvas itself is resized -- for doing this, use a [bind] to the canvas' event for calling the same resizing procedure. 5) The resizing procedure must initially check again if the scrollbar(s) is/are needed, because their visibility affects the canvas size -- call the same procedure described in item 3 for each axis. Then, retrieve the canvas size with '''[winfo] width''' and/or '''[winfo] height''' and use this information with the command ''$canvas'' '''itemconfigure''' ''$innerframeID''. I found out that '''[update idletasks]''' is needed in the middle of this procedure for ensuring that the retrieved canvas measures are valid. Finally, the canvas ''-scrollregion'' option must be configured for scrolling to work: a canvas has a virtual size of 32k X 32k pixels and this option defines which portion of the area will be "available" in the canvas window. In our case, this portion is exactly the inner frame, so the value for ''-scrollregion'' can be the result of ''$canvas'' '''bbox''' ''$innerframeID''. As soon as I can clean the code I wrote with this logic, I will post it here. I hope that one of the Tk gurus out there can suggest a more efficient algorithm! <>Scrollbar