Trouble with scrolling on a TK frame

Hi together,

Fist: Against all common sense I post a question without having read for a few days in this group.
However, I used groups.google and the apropriate faqs in the www but all I could come up with were examples that do not exactly cover my problem, or python code which also doesn't help so much.

Here is my problem:
I want to have a GUI in a "Excel" - like way: displaying a long list of data made up from different widgets. Since this list will grow quite long, I need to scroll that list.

Here is what I gathered so far:
I understand that I cannot scroll a Frame (which I use to arrange my widgets in a grid) so I wanted to use a canvas (which can be scrolled) and paint my widgets to that.
However, now I can scroll the canvas but not the frame on top of that.

Here is the code I am unhappy with:

     require 'tk'
     root = TkRoot.new() { title "Canvas, Grid, and Scrollbars" }
     vbar = TkScrollbar.new(root) { orient 'vert' }
     canvas = TkCanvas.new(root) {
             width 320
             height 200
             scrollregion '0 0 400 400'
     }
     canvas.yscrollbar(vbar)

     TkGrid.grid(canvas, vbar, 'sticky'=>'ns')

     TkGrid.columnconfigure(root, 0, 'weight'=>1)
     TkGrid.rowconfigure( root, 0, 'weight'=>1)

     TkcLine.new(canvas, 0, 0, 400, 400)
     TkcLine.new(canvas, 0, 400, 400, 0)

···

################
# commenting these lines will result in a scrollable cross on the canvas

     frame = TkFrame.new(canvas).grid

     for i in 1..10
       button = TkButton.new(frame, 'text'=>i)
       button.grid
     end
################

     Tk.mainloop

As a relative newbie to both TK and Ruby (I wrote a minor project with REXML about 5 years ago but never really returned to Ruby after that), any help would be very much appreciated.

Thanks and regards,
Andreas.

Perhaps this example will help. It's pretty rough, but I think it might point you in the right direction. It also illustrates some alternative ways of setting up widgets with Ruby/Tk. I'm not saying these alternatives are necessarily better what you did -- just thought you might like to know they exist. They do save on typing.

<code>
# Demonstrates adding a vetical row of buttons to a scrolling canvas.

require 'tk'

Tk.root.title("Test")

canvas = TkCanvas.new(Tk.root) {
    width 320
    height 200
    scrollregion '0 0 400 400'
    pack(:side => :left, :fill => :both, :expand => :true )
}

vbar = TkScrollbar.new(Tk.root) {
    orient 'vert'
    pack(:side => :right, :fill => :y)
    }

canvas.yscrollbar(vbar)

frame = TkFrame.new(canvas) do |frm|
    (1..10).each do |i|
       TkButton.new(frm) {
          text i
          command { Tk.bell }
          grid
       }
    end
end

TkcLine.new(canvas, 0, 0, 400, 400)
TkcLine.new(canvas, 0, 400, 400, 0)
TkcWindow.new(canvas, 200, 200, :width=>100, :height=>280, :window=>frame)

Tk.mainloop
</code>

I think the above does what you were asking for -- at least the button array scrolls with the canvas and the buttons beep when clicked (which proves that they function).

Regards, Morton

···

On Jun 23, 2007, at 4:00 PM, Andreas Pinkert wrote:

Here is my problem:
I want to have a GUI in a "Excel" - like way: displaying a long list of data made up from different widgets. Since this list will grow quite long, I need to scroll that list.

Here is what I gathered so far:
I understand that I cannot scroll a Frame (which I use to arrange my widgets in a grid) so I wanted to use a canvas (which can be scrolled) and paint my widgets to that.
However, now I can scroll the canvas but not the frame on top of that.

Here is the code I am unhappy with:

    require 'tk'
    root = TkRoot.new() { title "Canvas, Grid, and Scrollbars" }
    vbar = TkScrollbar.new(root) { orient 'vert' }
    canvas = TkCanvas.new(root) {
            width 320
            height 200
            scrollregion '0 0 400 400'
    }
    canvas.yscrollbar(vbar)

    TkGrid.grid(canvas, vbar, 'sticky'=>'ns')

    TkGrid.columnconfigure(root, 0, 'weight'=>1)
    TkGrid.rowconfigure( root, 0, 'weight'=>1)

    TkcLine.new(canvas, 0, 0, 400, 400)
    TkcLine.new(canvas, 0, 400, 400, 0)

################
# commenting these lines will result in a scrollable cross on the canvas

    frame = TkFrame.new(canvas).grid

    for i in 1..10
      button = TkButton.new(frame, 'text'=>i)
      button.grid
    end
################

    Tk.mainloop

Thanks a lot!

I added only this line to my code and now it does what I want:
TkcWindow.new(canvas, 200, 200, :width=>100, :height=>280,
    :window=>frame)

I have not found documentation on TkcWindow.
Where can I find such? I mean, I do not know what the API actually does.

regards,
Andreas.

Morton Goldberg wrote:

···

On Jun 23, 2007, at 4:00 PM, Andreas Pinkert wrote:

Here is my problem:
I want to have a GUI in a "Excel" - like way: displaying a long list of data made up from different widgets. Since this list will grow quite long, I need to scroll that list.

Here is what I gathered so far:
I understand that I cannot scroll a Frame (which I use to arrange my widgets in a grid) so I wanted to use a canvas (which can be scrolled) and paint my widgets to that.
However, now I can scroll the canvas but not the frame on top of that.

Here is the code I am unhappy with:

    require 'tk'
    root = TkRoot.new() { title "Canvas, Grid, and Scrollbars" }
    vbar = TkScrollbar.new(root) { orient 'vert' }
    canvas = TkCanvas.new(root) {
            width 320
            height 200
            scrollregion '0 0 400 400'
    }
    canvas.yscrollbar(vbar)

    TkGrid.grid(canvas, vbar, 'sticky'=>'ns')

    TkGrid.columnconfigure(root, 0, 'weight'=>1)
    TkGrid.rowconfigure( root, 0, 'weight'=>1)

    TkcLine.new(canvas, 0, 0, 400, 400)
    TkcLine.new(canvas, 0, 400, 400, 0)

################
# commenting these lines will result in a scrollable cross on the canvas

    frame = TkFrame.new(canvas).grid

    for i in 1..10
      button = TkButton.new(frame, 'text'=>i)
      button.grid
    end
################

    Tk.mainloop

Perhaps this example will help. It's pretty rough, but I think it might point you in the right direction. It also illustrates some alternative ways of setting up widgets with Ruby/Tk. I'm not saying these alternatives are necessarily better what you did -- just thought you might like to know they exist. They do save on typing.

<code>
# Demonstrates adding a vetical row of buttons to a scrolling canvas.

require 'tk'

Tk.root.title("Test")

canvas = TkCanvas.new(Tk.root) {
   width 320
   height 200
   scrollregion '0 0 400 400'
   pack(:side => :left, :fill => :both, :expand => :true )
}

vbar = TkScrollbar.new(Tk.root) {
   orient 'vert'
   pack(:side => :right, :fill => :y)
   }

canvas.yscrollbar(vbar)

frame = TkFrame.new(canvas) do |frm|
   (1..10).each do |i|
      TkButton.new(frm) {
         text i
         command { Tk.bell }
         grid
      }
   end
end

TkcLine.new(canvas, 0, 0, 400, 400)
TkcLine.new(canvas, 0, 400, 400, 0)
TkcWindow.new(canvas, 200, 200, :width=>100, :height=>280, :window=>frame)

Tk.mainloop
</code>

I think the above does what you were asking for -- at least the button array scrolls with the canvas and the buttons beep when clicked (which proves that they function).

Regards, Morton

Thanks a lot!

I added only this line to my code and now it does what I want:
TkcWindow.new(canvas, 200, 200, :width=>100, :height=>280, :window=>frame)

I suggest you also change

     frame = TkFrame.new(canvas).grid

to

     frame = TkFrame.new(canvas)

since you're putting the frame into a TkcWindow.

I have not found documentation on TkcWindow. Where can I find such? I mean, I do not know what the API actually does.

I know of no English documentation for Ruby/Tk, except

     http://raa.ruby-lang.org/project/rubytk_en/

which is rather sparse and somewhat out of date. One has to fall back on Perl/Tk documentation. Two sites I visit are:

     ActiveState Community - Boosting coder and team productivity with ready-to-use open source languages and tools.

     http://www-users.cs.umn.edu/~amundson/perl/perltk/toc.html

Of course, reading the Ruby/Tk library source code can be helpful.

There are many Ruby/Tk examples that you can learn from posted at:

     http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ext/tk/sample/

In particular, you will want to look at scrollframe.rb. It is highly relevant to your problem.

Regards, Morton

···

On Jun 24, 2007, at 8:10 AM, Andreas Pinkert wrote: