| Hello, World! | Simple Widgets | Binding Events | More Widgets | Scrollbars | Menus | Canvas | Make things look Beautiful | More Information |
| We are moving to this wiki |
|---|
We have already seen you can put widgets in the root window. Tk provides one
specific widget for grouping: the TkFrame. It
behaves the same as a root, though it has a few options that differ. Here is an
example:
root = TkRoot.new() { title "More Widgets" }
frame = TkFrame.new(root).pack("side"=>"right")
buttons = TkFrame.new(frame).pack("side"=>"bottom")
load = TkButton.new(buttons) { text "Load" }
save = TkButton.new(buttons) { text "Save" }
TkGrid.configure(load, save)
There really is not much to say about this.
Well, we could have done this with only one frame. Let us continue the
example and see what happens.
display = TkFrame.new(root).pack("side"=>"left")
editor = TkText.new(display).pack() # top
status = TkLabel.new(display) { text "launching..." }
status.pack("side"=>"bottom", "anchor"=>"w")
list = TkListbox.new(frame).pack()
list.insert("end", "/some/file")
list.insert("end", "/etc/hosts")
Still nothing special happened, but you should get an idea where we are going
with the application, right? What a TkListbox
is, I hear you ask? It displays a list and we will come back to it when we
discuss scrollbars.
list.pack("fill"=>"y")
Yes, simply add it at the end of the script (well, before Tk.mainloop, of course). Calling pack is configuring the packing procedure, as well as
calling it again. This can be useful to add buttons on the fly, in response to
what a user does.
Surprise, that does not work! Why not? Because list never got any more space to display itself
in. Which widget might give it space? Right, the frame that packs it.
frame.pack("fill"=>"y")
Something happened, but not what we intended! The frame filled vertically, all right, but the list did not. That is because the frame gives the list
space in the tophalf of the screen, according to its height. The only direction
in which the list can fill is horizontally! We will solve this below.
display.pack("fill"=>"both", "expand"=>true)
editor.pack("fill"=>"both", "expand"=>true)
list.pack("expand"=>true)
We want editor to take whatever space
possible. Broad buttons or a high status label are useless. So editor needs to fill
whatever space assigned, in "both" directions
and it needs to expand to grab that
extra space.
The same holds for display, the frame that contains editor and for list that needs to expand vertically.
Anything unequal to zero will tell Tk to actually expand. We think true is a nice Ruby construct to use here.
On the other hand, a TkMessage, though multiline, will almost never need to fill and expand.
status.pack("before"=>editor)
All stuff with the list and buttons is already in what we think is the right
order.
This who-first may seem irrelevant, but is extremely important when you port your applications to smaller (or bigger) screens. The author owns an iPAQ and is very happy with these orderings. A window manager like ion has other ideas of sizes assigned to windows than Tk and usually wins.
| Hello, World! | Simple Widgets | Binding Events | More Widgets | Scrollbars | Menus | Canvas | Make things look Beautiful | More Information |