See Also edit
- Comparing Geometry Managers
- A Program In Tcl/Tk To Demonstrate The Three Geometry Managers : pack, grid and place
- Stacking Order
- an aspect of geometry management
Reading edit
- Windownamager geometry problem , comp.lang.tcl ,2002-06-04
- KBK gives a good description of the requested versus the actual geometry of a widget
Tk geometry managers edit
- place
- precise placement of a widget in absolute coordinates, for when you want to roll your own geometry manager
- pack
- widgets flow around each other in the available space
- grid
- available space is devided into numbers sectors to which widgets are either manually or automatically assigned. Somewhat more direct and intuitive than pack.
Other Geometry Managers edit
- BLT's table geometry manager
- layout
- a Tk front-end that calls the standard geometry managers with a different interface
- Tix's form geometry manager
- TkVSform
- does geometry management (along with other things) for its forms
- GRIDPLUS2
- is a screen layout package built on the Tk grid manager
- making your own geometry manager
Description edit
Choose grid for tabular layouts, and when there's no good reason to choose something else. Choose pack if you're used to the web browser box model, and the flow makes sense to you. Choose place when you want as little help as possible managing the layout.Introspection edit
Introspection on geometry managers is possible:winfo manager $widgetNotice that
winfo manager $toplevelreturns the special value, wm.
Horizontal Stretch of One Widget, But No Vertical Stretch of Either Widget edit
Harald Kirsch: Is it possible with place to position a widget .f.bot just below another widget .f.top such that the following holds:- If the container .f is resized vertically, both widgets keep their natural height and keep sticked to the top of .f
- If .f is resized horizontally, .f.top keeps it natural width and stays sticked to the left border of .f while .f.bot resizes itself to stretch over the whole width of .f.
# Basic Setup frame .f -bg red label .f.top -text "I'm top" -bg yellow label .f.bot -text "I'm bot" -bg white pack .f -fill both -expand 1 # Geometry Manager Magic set w1 [winfo reqwidth .f.top] set w2 [winfo reqwidth .f.bot] if {$w1<$w2} {set w1 $w2} set h [expr {[winfo reqheight .f.top]+[winfo reqheight .f.bot]}] .f configure -width $w1 -height $h place .f.top -x 0 -y 0 place .f.bot -x 0 -y [winfo reqheight .f.top] -relwidth 1Did you know that you can also achieve the same effect using grid?
# Basic Setup frame .f -bg red label .f.top -text "I'm top" -bg yellow label .f.bot -text "I'm bot" -bg white pack .f -fill both -expand 1 # Geometry Manager Magic grid .f.top -sticky w grid .f.bot -sticky ew grid columnconfigure .f 0 -weight 1 grid rowconfigure .f 2 -weight 1 -minsize 0And also pack?
# Basic Setup frame .f -bg red label .f.top -text "I'm top" -bg yellow label .f.bot -text "I'm bot" -bg white pack .f -fill both -expand 1 # Geometry Manager Magic pack .f.top -side top -anchor w pack .f.bot -side top -anchor nw -fill x -expand 1
DKF:Many widgets have -width and -height options, but those do not usually give useful results when read (for the purposes of geometry management.) winfo width and winfo height would be more useful you'd think, but in fact they only ever report the current size of a widget, which is initially zero as there hasn't been time to work it out yet (since interaction with geometry managers is performed on idle updates.) To get the info you need for GM, you need winfo reqheight and winfo reqwidth commands, which report what size widgets would prefer to be.The other thing you need to watch out for if you are doing any fancy geometry mangling (unlike the simple example above) is the <Configure> event. This lets you find out when the enclosing widget changes in size due to whatever GM is managing it. A sophisticated example that uses the configure events is available at [1].
KBK: You also need to include update idletasks in the case where another geometry manager is managing the winfo reqwidth or winfo reqheight of the widget. It is possible that the requested size is zero because a subordinate geometry manager hasn't had the chance to work out the size.
Using Text Widget As a Flowing Geometry Manager edit
[Michail Richardson]: Is it possible with pack to position a series of widgets in a frame such that if they all fit in the horizontal space, then they are arranged that way. Otherwise, they are folded like text. A sort of message window for frames. This is so that a series of radiobuttons that exceeds the width of the user's screen can properly be displayed, in, e.g. tkGnats. (The list of buttons is determined at run-time)KBK: Sure. Window them in a text widget. There's an example in the "Widget Tour" that comes with Tk that does just what you're asking.escargo: This sounds like the Java flow layout.Using pack and grid Together edit
Lars H: In the following example, the main structure uses grid, but the "toolbar" frame on the top uses pack internally. Widgets named something ending in _c are canvases, ending in _h horizontal scrollbars, and those ending in _v are vertical scrollbars.set t [toplevel .rulebrowser] wm title $t "Rule browser" # First create some things to manage foreach c_ [list $t.left_ $t.right_] { scrollbar ${c_}h -orient horiz -command [list ${c_}c xview] scrollbar ${c_}v -command [list ${c_}c yview] canvas ${c_}c -width 200 -height 400 -relief solid -borderwidth 1\ -xscrollcommand [list ${c_}h set] -yscrollcommand [list ${c_}v set]\ -scrollregion {0 0 300 500} } # Then start managing grid $t.left_c -row 2 -column 0 -sticky nsew grid $t.right_c -row 2 -column 3 -sticky nsew grid $t.left_v -row 2 -column 1 -sticky ns grid $t.right_v -row 2 -column 4 -sticky ns grid $t.left_h -row 3 -column 0 -sticky ew grid $t.right_h -row 3 -column 3 -sticky ew grid rowconfigure $t 2 -weight 1 grid columnconfigure $t 0 -weight 1 grid columnconfigure $t 3 -weight 1 canvas $t.arrow_c -width 20 -height 20 $t.arrow_c create line {0 10 20 10} -arrow last -width 2 grid $t.arrow_c -row 2 -column 2 scrollbar $t.text_v -command [list $t.text_t yview] text $t.text_t -height 5 -yscrollcommand [list $t.text_v set] grid $t.text_t - - - -row 1 -column 0 -sticky nsew grid $t.text_v -row 1 -column 4 -sticky ns set bg grey90 frame $t.f -background $bg grid $t.f - - - - -row 0 -column 0 -sticky ew pack [button $t.f.prev -text "Prev" -highlightbackground $bg] -side left pack [button $t.f.next -text "Next" -highlightbackground $bg] -side left pack [button $t.f.go -text "Go" -highlightbackground $bg] -side right pack [entry $t.f.go_e -width 4] -side right pack [label $t.f.go_l -text "Rule" -background $bg] -side right