From: David Bailey <david.bailey / technologist.com>
Subject: Placing Sets of Ruby/Tk Widgets
Date: Mon, 3 Apr 2006 01:25:46 +0900
Message-ID: <a7f7f39d82de1edae4a7f0b9cd8b640d / ruby-forum.com>
> But then I got angry (both with myself and Ruby/Tk) and became 
> determined to figure it out without asking.
> 
> It took me hours and hours, but I fainally "nailed" it!  The source of 
> my frustration was not realizing that the (:x,:y) coordinates were 
> relative to the parent widgets' origin (in my example these are TkRoot 
> and TkFrames).

Please cool down. :-)
Probably, Pack geometry manager is enough for your case.

In many cases, Pack geometry manager is good choice.
In many cases of others (e.g. layout a widget with both of a horizontal 
and a vertical scrollbar), Grid geometry manager is suitable.
And in extremely rase case, Place geometry manager (or layout on the 
canvas widget) is necessary. 

I think that it is not difficult to study Pack geometry manager. 
Its strategy of layout is simple but working very well.
The following is rewrite-version of your example with Pack.
Please see that there is no coordinate except putting a widget on 
a canvas widget and there are minimum controls to fix the widget size.
-----------------------------------------------------------------------
require 'tk'

root=TkRoot.new(:title=>'Ruby/Tk Geometry, Frame, Canvas, ' + 
                'and Widget Meanderings', :geometry=>'705x700')

#-----------------------------------
topFrame = TkFrame.new(root, :height=>100, :borderwidth=>5, :relief=>:groove, 
                       :background=>:pink).pack(:fill=>:x, :expand=>false)
topFrame.pack_propagate(false) # if you must keep the height of the frame.

topFrameButton1 = TkButton.new(topFrame, :text=>'TFButton 1')
topFrameButton1.pack(:side=>:left, :anchor=>:nw)

#-----------------------------------
middleFrame = TkFrame.new(root).pack(:fill=>:both, :expand=>true)

#-----------------------------------
middleLeftFrame = TkFrame.new(middleFrame, :width=>100, :borderwidth=>5, 
                              :relief=>:groove, :background=>:cyan)
middleLeftFrame.pack(:side=>:left, :fill=>:y, :expand=>false)

middleLeftFrameButton1 = TkButton.new(middleLeftFrame, :text=>'MLFButton 1')
middleLeftFrameButton1.pack(:fill=>:x, :expand=>false)

middleLeftFrameButton2 = TkButton.new(middleLeftFrame, :text=>'MLFButton 2')
middleLeftFrameButton2.pack(:fill=>:x, :expand=>false)

#-----------------------------------
middleCenterFrame = TkFrame.new(middleFrame, :borderwidth=>5, 
                                :relief=>:groove, :background=>:blue)
middleCenterFrame.pack(:side=>:left, :fill=>:both, :expand=>true)

middleCenterCanvas = TkCanvas.new(middleCenterFrame, :borderwidth=>5, 
                                  :relief=>:groove, :background=>:yellow)
middleCenterCanvas.pack(:fill=>:both, :expand=>true, :padx=>5, :pady=>5)

middleCenterCanvasButton1 = TkButton.new(middleCenterCanvas, 
                                         :text=>'MCCButton 1')

# ??? Do you want to put the button "ON" the canvas?
# middleCenterCanvasButton1.place(:x=>0,:y=>0)
canvasButton1Win = TkcWindow.new(middleCenterCanvas, [0, 0], :anchor=>:nw, 
                                 :window=>middleCenterCanvasButton1)

#-----------------------------------
middleRightFrame = TkFrame.new(middleFrame, :width=>105, :borderwidth=>5, 
                               :relief=>:groove, :background=>:green)
middleRightFrame.pack(:side=>:left, :fill=>:y, :expand=>false)

middleRightFrameButton1 = TkButton.new(middleRightFrame, :text=>'MRFButton 1')
middleRightFrameButton1.pack(:fill=>:x, :expand=>false)

#-----------------------------------
bottomFrame = TkFrame.new(root, :height=>100, 
                          :borderwidth=>5, :relief=>:groove, 
                          :background=>:orange).pack(:fill=>:x, :expand=>false)
bottomFrame.pack_propagate(false) # if you must keep the height of the frame.

bottomFrameButton1 = TkButton.new(bottomFrame, :text=>'BFButton 1', :command=>proc{p root.geometry}
)
bottomFrameButton1.pack(:side=>:left, :anchor=>:nw)

#-----------------------------------
ev_quit = TkVirtualEvent.new('Control-c', 'Control-q', 'q')
Tk.root.bind(ev_quit, proc{Tk.exit}).focus
Tk.mainloop
-----------------------------------------------------------------------
-- 
Hidetoshi NAGAI (nagai / ai.kyutech.ac.jp)