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