Hidetoshi NAGAI wrote:
> From: Ed Redman <redman / accesswave.ca>
> Subject: ruby/tk and loop delay
> Date: Mon, 14 Apr 2008 08:20:05 +0900
> Message-ID: <4ywMj.10891$682.6491@edtnps90>
>> I have a Tk_button(shuffle) that shuffles the cards and places them on a 
>> canvas.The shuffle works fine but I would like to have a slight delay 
>> between between each card being displayed on the canvas. Below is the 
>> shuffle buttons command. I would like to delay the loop each time so 
>> their is a slight delay. I have tried putting Tk.after(time)
>> { part around the loop} but it just delays the shuffle and is not
>> visible. Not each card being displayed.  I need a little direction 
>> on implementing such a loop
> 
> On Tk, re-drawing widgets occurs when idle-tasks.
> The callback operation for button click is only one event.
> Tk doesn't call idle loop before finishing of the callback.
> If you want to force idle loop, please call "Tk.update" or
> "Tk.update_idletasks" at when you need.
> 
> However, I don't recommend such long term operation on one callback.
> Such callbacks may block callbacks for other events.
> That is, you may get bad response of GUI.
> 
> I think that Thread + TkTimer is better for your case.
> ----------------------------------------------------------
> proc exchange{|nr, nm|
>   newhash[nr], newhasn[nm] = newhash[nm], newhasn[nr]
>   place[nr].image newhash[nr]
>   place[nm].image newhash[nm]
>   # Tk.update   ### if you need
> }
> 
> # 100ms interval, 52 times
> tm = TkTimer.new(100, 52){ exchange.call(rand(56), rand(56)) }
> 
> shuffle.command{
>   shuffle.state(:disable)
>   Thread.new{ tm.start.wait; shuffle.state(:normal) }
> }
> ----------------------------------------------------------
> On this code, the callback for clicking 'shuffle' button
> will finish in short term.
> And GUI can treat the next event soon, although 'shuffle' button
> is disabled.
> The thread created on the callback starts and waits the timer,
> and enable 'shuffle' button when the timer is finished.
> 
> # I should add the method to entry a proc executed at end of a timer.
> # Then, a thread isn't required for such operataion.


Isn't after() supposed to accomplish the same thing?  Why doesn't 
after() work in my code in my previous post?

I tried my own threading solution, but it didn't work--there was no 
delay when drawing lines to a Canvas widget:

require 'tk'

def do_press(e)
  widget = e.widget
  x = e.x
  y = e.y


  10.times do |i|
    x += 10
    TkcLine.new(widget, x, y, x+100, y+100)

    t = Thread.new do
      sleep(2)
      widget.update
    end

  end
end



root = TkRoot.new {title 'Canvas Test'}
canvas = TkCanvas.new(root)
canvas.pack

canvas.bind('ButtonRelease-1', lambda {|e| do_press(e)})
Tk.mainloop
-- 
Posted via http://www.ruby-forum.com/.