Hello, World! Simple Widgets Binding Events More Widgets Scrollbars Menus Canvas Make things look Beautiful More Information

We are moving to this wiki

Packing some Simple Widgets

A single window with a single label is not very much. We will start with packing five, basic widgets. The second part of this page looks at placing widgets in a regular grid.
require 'tk'

root = TkRoot.new() { title "Packing Example" }

button = TkButton.new(root) { text "First, rightmost" }
button.pack("side"=>"right", "fill"=>"y")

entry = TkEntry.new(root).pack("side"=>"top", "fill"=>"x")
entry.insert(0, "Entry on the top")

label = TkLabel.new() { text "to the right" }
label.pack("side"=>"right")

image = TkPhotoImage.new('file'=>"background.gif", 'height'=>50)
img_label = TkLabel.new(root) { image image }.pack("anchor"=>"e")

text = TkText.new(root) { width 20; height 5 }.pack("side"=>"left")
text.insert('end', "Left in canvas")

TkMessage.new(root) { text "Message in the Bottom" }.pack("side"=>"bottom")

Tk.mainloop()
That's not too daunting, is it? Let's walk through the source:

Button


Entry
Label
Image
Text
Message

Resizing the Window

If you now resize the window, you see that the widgets are automatically repacked. When you enlarge the window, you can see better where widgets are placed by the packer.

When you shrink the window, you will see widgets gradually disappearing. The widgets that were added last, are packed last and find no space left. The message and text are bound to go first. Notice that the text widget spreads all text over multiple lines when you shrink it (yes, you can tell it to wrap on word boundaries with wrap "word").

Finally, if you do like the order in which you construct the widgets, but do not like them to be packed in that order, you can use before before otherWidget and after otherWidget as options for pack.

Gridding some Simple Widgets

As alternative, when packing seems to be rude, there is grid. Gridding allows you to align widgets, which is troublesome when packing. The OO nature of Ruby makes gridding a bit cumbersome, since you can not grid a set of widgets by calling a method of just one of them.

Here is some code:

require 'tk'

root = TkRoot.new() { title "Gridding Example" }

br = ["one", "and", "one"].collect { |c|
  TkButton.new(root, "text"=>c)
}
TkGrid.grid(br[0], br[1], br[2], "columnspan"=>2 )

TkButton.new(root, "text"=>"is").grid("columnspan"=>3, "sticky"=>"ew")
TkButton.new(root, "text"=>"two").grid("row"=>1, "column"=>3, "columnspan"=>3)

Tk.mainloop

First, we construct three buttons, then we add them in a single row of the grid. Due to the columnspan, we now have six columns in our grid.

The fourth button is automatically added to the next row, since we do not mention any row. In much the same way, it is added to the first column. It demands three columns and due to sticky, the button is assigned the entire width of those three columns. Sticky delivers a combination of the anchor and fill when packing.

The last button is added explicitly to its row and column, because otherwise it would be added to the third row, first column (it is a new grid command).

The options ipadx, pady and in work the same as when packing.

widget.grid_columnconfig and widget.grid_rowconfig do not work in current Ruby/Tk, but I sent a fix to the ruby-dev mailinglist.

Resizing the Window

When you resize the window, there is nothing interesting to see. For more resizing issues, see the chapter on combining more widgets.
Hello, World! Simple Widgets Binding Events More Widgets Scrollbars Menus Canvas Make things look Beautiful More Information

Kero