Placing Sets of Ruby/Tk Widgets

Discussion in 'Ruby' started by David Bailey, Apr 2, 2006.

  1. David Bailey

    David Bailey Guest

    After a whole day of frustrating "experimentation" with no good results,
    I was ready to give up and ask this question:

    How do I place two vertical sets of widgets (inside of a left and right
    frame), two horizontal set of widgets (inside of a top and bottom frame)
    and one set of rectanges in a square grid (inside of a middle center
    canvas in a middle center frame) to control the location of my "sets"?

    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).

    If you want to take a look (where I've use :background, :borderwidth and
    :relief options to make the frames and canvas stand out), here is the
    Ruby code:

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

    packer1 = { :fill=>:none }

    # Note: These (x,y) coordinates are relative to the parent widget's
    # (TkRoot's or TkFrame's) origin
    placer1 = { :x=>0, :y=>0 }; placer2 = { :x=>0, :y=>600 }
    placer3 = { :x=>0, :y=>40 }; placer4 = { :x=>100, :y=>100 };
    placer5 = { :x=>600, :y=>100 }; placer6 = { :x=>0, :y=>100 }

    topFrame = TkFrame.new(root, :width=>705, :height=>100, \
    :borderwidth=>5, :relief=>:groove, :background=>:pink).place(placer1)
    topFrameButton1 = TkButton.new(topFrame, :text=>'TFButton 1').\
    place(placer1)

    middleLeftFrame = TkFrame.new(root, :width=>100, :height=>500, \
    :borderwidth=>5, :relief=>:groove, :background=>:cyan).place(placer6)
    middleLeftFrameButton1 = TkButton.new(middleLeftFrame, :text=>\
    'MLFButton 1').place(placer1)
    middleLeftFrameButton2 = TkButton.new(middleLeftFrame, :text=>\
    'MLFButton 2').place(placer3)

    middleCenterFrame = TkFrame.new(root, :width=>500, :height=>500, \
    :borderwidth=>5, :relief=>:groove, :background=>:blue).place(placer4)
    middleCenterCanvas = TkCanvas.new(middleCenterFrame, :width=>477, \
    :height=>477, :borderwidth=>5, :relief=>:groove,
    :background=>:yellow).\
    pack(packer1)
    middleCenterCanvasButton1 = TkButton.new(middleCenterCanvas, :text=>\
    'MCCButton 1').place(placer1)

    middleRightFrame = TkFrame.new(root, :width=>105, :height=>500, \
    :borderwidth=>5, :relief=>:groove, :background=>:green).place(placer5)
    middleRightFrameButton1 = TkButton.new(middleRightFrame, :text=>\
    'MRFButton 1').place(placer1)

    bottomFrame = TkFrame.new(root, :width=>705, :height=>100, \
    :borderwidth=>5, :relief=>:groove,
    :background=>:eek:range).place(placer2)
    bottomFrameButton1 = TkButton.new(bottomFrame, :text=>'BFButton 1').\
    place(placer1)

    ev_quit = TkVirtualEvent.new('Control-c', 'Control-q', 'q')
    Tk.root.bind(ev_quit, proc{Tk.exit}).focus
    Tk.mainloop

    --
    Posted via http://www.ruby-forum.com/.
    David Bailey, Apr 2, 2006
    #1
    1. Advertising

  2. From: David Bailey <>
    Subject: Placing Sets of Ruby/Tk Widgets
    Date: Mon, 3 Apr 2006 01:25:46 +0900
    Message-ID: <>
    > 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=>:eek:range).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 ()
    Hidetoshi NAGAI, Apr 3, 2006
    #2
    1. Advertising

  3. David Bailey

    David Bailey Guest

    Hidetoshi NAGAI wrote:
    >
    > Please cool down. :)
    > Probably, Pack geometry manager is enough for your case.
    >
    > -----------------------------------------------------------------------
    > bottomFrameButton1 = TkButton.new(bottomFrame, :text=>'BFButton 1',
    > :command=>proc{p root.geometry}
    > )



    Wow! Once again, brute force must bow to finesse!

    I did not notice the pack_propagate() method, before. That was key.

    Also, what does the bottomFrameButton1's "{:command=>{p root.geometry}"
    do? And why did you NOT use it in the topFrameButton1?

    Thanks.

    P.S. Yes, I will cool down. :)>)

    --
    Posted via http://www.ruby-forum.com/.
    David Bailey, Apr 3, 2006
    #3
  4. David Bailey

    David Bailey Guest

    David Bailey wrote:
    > Also, what does the bottomFrameButton1's "{:command=>{p root.geometry}"
    > do? And why did you NOT use it in the topFrameButton1?
    >


    Oh, you're just printing out the geometry when the button is clicked.
    Bingo!

    --
    Posted via http://www.ruby-forum.com/.
    David Bailey, Apr 3, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?ISO-8859-1?Q?Mickel_Gr=F6nroos?=

    Placing entry widgets on a canvas in Tkinter

    =?ISO-8859-1?Q?Mickel_Gr=F6nroos?=, Jun 30, 2003, in forum: Python
    Replies:
    0
    Views:
    418
    =?ISO-8859-1?Q?Mickel_Gr=F6nroos?=
    Jun 30, 2003
  2. =?ISO-8859-1?Q?Mickel_Gr=F6nroos?=

    Re: Placing entry widgets on a canvas in Tkinter

    =?ISO-8859-1?Q?Mickel_Gr=F6nroos?=, Jun 30, 2003, in forum: Python
    Replies:
    0
    Views:
    957
    =?ISO-8859-1?Q?Mickel_Gr=F6nroos?=
    Jun 30, 2003
  3. John Maclean
    Replies:
    3
    Views:
    104
    John Maclean
    Jan 25, 2006
  4. John Maclean

    Ruby Tk - embedding widgets

    John Maclean, Jan 25, 2006, in forum: Ruby
    Replies:
    0
    Views:
    90
    John Maclean
    Jan 25, 2006
  5. Dung Ping
    Replies:
    1
    Views:
    138
    Randy Webb
    Feb 27, 2005
Loading...

Share This Page