Ruby/Tk refresh problem

Hello,
I am using Ruby 1.8.7 with Tk. The code runs fine. However, a few
instructions that I set while the program is busy (basically before
starting heavy computation it sets a TkLabel to display “Busy”… and
once it’s done it sets it back to “”) do not seem to have much of an
effect.

My fear is that it might be a problem like refreshing, whereby Tk
doesn’t receive the instruction until it’s too late. Is there a way to
flush all the instructions to Tk and let it do its magic before
continuing running my code?

Thanks.

Diego

From: Diego V. [email protected]
Subject: Ruby/Tk refresh problem
Date: Mon, 6 Apr 2009 19:39:15 +0900
Message-ID:
[email protected]

I am using Ruby 1.8.7 with Tk. The code runs fine. However, a few
instructions that I set while the program is busy (basically before
starting heavy computation it sets a TkLabel to display “Busy”… and
once it’s done it sets it back to “”) do not seem to have much of an
effect.

Maybe, you call the heavy computation IN a callback.
If so, that is a very bad way on event-driven programing.

The heavy part blocks the eventloop.
And then, the GUI cannot receive any events.
That is, the GUI seems to freeze.

A callback procedure should return as soon as possible.
One of the simple way to do that is to make a thread executing the
heavy computation.
Of course, you never join the thread in a callback.
Instead of joining, you should generate an event (TkVariable#wait may
be useful) to tell the finishing of the thread.

For example, the following is a bad sample.

require ‘tk’
l = TkLabel.new(:text=>‘MESSAGE’).pack
TkTimer.new(500, -1,
proc{l.foreground ‘black’},
proc{l.foreground ‘red’}).start
TkButton.new(:text=>‘start heavy work’,
:command=>proc{10.times{|n| sleep 1; p n}}).pack
Tk.mainloop

When clicking the button, this GUI seems to freeze.

Please compare with the following.

require ‘tk’
l = TkLabel.new(:text=>‘MESSAGE’).pack
TkTimer.new(500, -1,
proc{l.foreground ‘black’},
proc{l.foreground ‘red’}).start
TkButton.new(:text=>‘start heavy work’,
:command=>proc{Thread.new{10.times{|n| sleep 1; p
n}}}).pack
Tk.mainloop

The following is another sample.

require ‘tk’
l = TkLabel.new(:text=>‘MESSAGE’).pack
TkTimer.new(500, -1,
proc{l.foreground ‘black’},
proc{l.foreground ‘red’}).start
b = TkButton.new(:text=>‘start heavy work’,
:command=>proc{
b.state :disable
Thread.new{
10.times{|n| sleep 1; p n}
b.state :normal
}
}).pack
Tk.mainloop

Have you tried “Tk.update” call ?

Antonio

Diego V. wrote:

Hello,
I am using Ruby 1.8.7 with Tk. The code runs fine. However, a few
instructions that I set while the program is busy (basically before
starting heavy computation it sets a TkLabel to display “Busy”… and
once it’s done it sets it back to “”) do not seem to have much of an
effect.

My fear is that it might be a problem like refreshing, whereby Tk
doesn’t receive the instruction until it’s too late. Is there a way to
flush all the instructions to Tk and let it do its magic before
continuing running my code?

Thanks.

Diego

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs