Forum: Ruby how to use threads in Tk/GUI

73700e119917433681f2e8f3e4369f74?d=identicon&s=25 Li CN (alex-osu3)
on 2014-06-17 05:37
Hi all,

I am learning Ruby threads  and  follow this
website(http://www.sitepoint.com/threads-ruby/)

#####################################
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?
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2014-06-18 01:19
....
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2014-06-18 01:25
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.
73700e119917433681f2e8f3e4369f74?d=identicon&s=25 Li CN (alex-osu3)
on 2014-06-18 03:41
Thank you so much, 7stud. The way to use threads in GUI is kind of
different from how it is used in a console.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.