Announcement (2017-05-07): www.ruby-forum.com is now read-only since I
unfortunately do not have the time to support and maintain the forum any
more. Please see rubyonrails.org/community and ruby-lang.org/en/community
for other Rails- und Ruby-related community platforms.

1) From the ruby/tk docs:
-----
Each separate widget is a Ruby object. When creating a widget, you must
pass its parent as a parameter to the widget class' "new" method. The
only exception is the "root" window, which is the toplevel window that
will contain everything else.
-----
2) Why would setting an option for a widget in a thread be any different
than just setting the option in the main thread? For instance, if I
want
to set the background color of a widget to the color red, would it make
any difference if I set that option in the main thread or if I started a
new thread and set the widget's background color to red? Similarly,
all you did in your threads was set an option for each of your buttons.
require 'tk'
$root=TkRoot.new() do
title "my window"
end
$button1=TkButton.new()do
text "button1"
pack()
end
$button2=TkButton.new()do
text "button2"
pack()
end
$button1[:command] = lambda {
Thread.new {
1.upto(10) do |i|
puts i
sleep rand()
end
}
}
$button2[:command] = lambda {
Thread.new {
('a'..'z').each do |ch|
puts ch
sleep rand()
end
}
}
#You call join() so that your program does not end before
#the other threads finish their work. However, in a tk
#program, calling mainloop() makes the main thread an
#infinite loop, so the other threads will always finish
#before the main thread--unless you kill the main
#thread by closing the root tk window.
Tk.mainloop
Run the program, then click each button quickly.