How to use threads in Tk/GUI

Hi all,

I am learning Ruby threads and follow this
website(Threads in Ruby — SitePoint)

#####################################
def calculate_sum(arr)
sleep(2)
sum = 0
arr.each do |item|
sum += item
end
sum
end

@items1 = [12, 34, 55]
@items2 = [45, 90, 2]
@items3 = [99, 22, 31]

threads = (1…3).map do |i|
Thread.new(i) do |i|
items = instance_variable_get(“@items#{i}”)
puts “items#{i} = #{calculate_sum(items)}”
end
end
threads.each {|t| t.join}

####################################

The example above makes sense to me. But how can I translate them into a
GUI?
Here are some similar codes and I don’t think threads work in my codes:

######my code####
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

th1=Thread.new{
$button1.command{(1…10).each{ |i| puts i; sleep rand()}}
}
th2=Thread.new{
$button2.command{(‘a’…‘z’).each{ |letter| puts letter; sleep rand()}}

}

th1.join
th2.join

Tk.mainloop

Any comments to make it work?

  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.

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

Thank you so much, 7stud. The way to use threads in GUI is kind of
different from how it is used in a console.