From: Valen Onish <valenonish / gmail.com>
Subject: Ruby/Tk - simple task that I'm srtuck
Date: Tue, 26 Jun 2007 20:44:06 +0900
Message-ID: <b60191be5fbf2368e9bc896c10520af4 / ruby-forum.com>
> but I see only the last colour.

You'll be able to see the changes by 'Tk.update_idletasks'.
For example,
-------------------------------------
def change_colour
  $lb_1.configure('background'=>'blue')
  Tk.update_idletasks
  sleep(0.5)
  $lb_1.configure('background'=>'green')
  Tk.update_idletasks
  sleep(0.5)
  $lb_1.configure('background'=>'gray')
end
-------------------------------------

However, that NEVER be a right solution, 
because a 'sleep' method on a callback procedure 
blocks Tk's eventloop.
Then, there are no drawing, no update of widgets, 
and no response to events.

I recommend you to use 'Tk.after' method or a TkTimer object.
For example, 

---< Tk.after >---------------------------------------
require 'tk'

root = TkRoot.new { title "Ruby/Tk  Example" }

lb_1 = TkLabel.new(root){
background "red"
foreground "blue"
text "Your area"
font "system,12"
place('relx'=>0.4, 'rely'=>0.08)
}

bt_toss=TkButton.new(root){
text "Toss"
command proc{change_colour(bt_toss, lb_1)}
place('relx'=>0.2, 'rely'=>0.78)
}

def change_colour(btn, lbl)
  btn.state = :disabled
  lbl.configure('background'=>'blue')
  Tk.after(500){lbl.configure('background'=>'green')}
  Tk.after(1000){lbl.configure('background'=>'gray'); btn.state = :normal}
#    OR
# Tk.after(500){
#   lbl.configure('background'=>'green')
#   Tk.after(500){lbl.configure('background'=>'gray'); btn.state = :normal}
# }
end

Tk.mainloop
------------------------------------------------------

In this case, it is better to disable the button while changing the
label's color.
If not disable, multiple clicks may break the changing order of colors.

If you want to allow multiple clicks, you have to stop the Tk.after
callbacks. It may bother you. 
In such case, TkTimer#restart is useful. 
For example, 

---< TkTimer >----------------------------------------
require 'tk'

root = TkRoot.new { title "Ruby/Tk  Example" }

lb_1 = TkLabel.new(root){
background "red"
foreground "blue"
text "Your area"
font "system,12"
place('relx'=>0.4, 'rely'=>0.08)
}

timer = TkTimer.new(500, 1,  # interval == 500ms  repeat == once
                    proc{|tm_obj| 
                      tm_obj.return_value.configure(:background => 'green')
                      # tm_obj.return_value == lb_1
                    },
                    proc{|tm_obj|
                      tm_obj.return_value.configure(:background => 'gray')
                    })

timer.set_start_proc(0,  # wait before start == 0 ms
                     proc{|tm_obj|
                       tm_obj.current_args[0].configure(:background => 'blue')
                       # tm_obj == TkTimer object
                       # tm_obj.current_args == [lb_1]
                       # return_value is lb_1
                       #    ( == tm_obj.return_value on the next callback )
                     }, lb_1)

bt_toss=TkButton.new(root){
text "Toss"
command proc{timer.restart}
place('relx'=>0.2, 'rely'=>0.78)
}

Tk.mainloop
------------------------------------------------------
-- 
Hidetoshi NAGAI (nagai / ai.kyutech.ac.jp)