Why won't my FXRuby widgets update?

Hi,

Anybody out there faced this ? (the code below is actually just the core
of the “babelfish” example). But there’s a “flaw” in the code that isn’t
mentioned in the documentation. Specifically, when the button press
invokes procAll, any updates to the widgets are sort of “queued up”
until procAll finishes and only then are they applied - I discovered
this by painstaking trial and error. What if I want procAll to go away
and process a load of stuff that might take 20 minutes, but I want to
update the screen with messages about progress and stuff. I just find
that I get nothing until procAll ends. Clearly I’ve missed a step with
setting up the messaging, but the documentation is persuading me that
there’s nothing more to do.

Can anybody tell me what’s wrong with the code below ? Why won’t the
text field show the text as soon as the data target is updated as the
documentation implies it will ? Other widgets behave in a similar
fashion with the exception of the progress bar which will update
immediately. Very peculiar. Any help appreciated.

Regards,
Graham Stokes

#!/usr/bin/env ruby
require ‘fox16’
include Fox

class Update_test < FXMainWindow

def initialize(app)
super(app, “Test”, nil, nil, DECOR_ALL,
0, 0, 600, 400, 0, 0)
controlsFrame = FXHorizontalFrame.new(self,
LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X)

btn = FXButton.new(controlsFrame, "Go", nil, nil, 0,
  BUTTON_NORMAL|LAYOUT_SIDE_RIGHT)
btn.connect(SEL_COMMAND, method (:procAll))

bottomFrame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y)
FXLabel.new(bottomFrame, "Text:", nil, LAYOUT_FILL_X)
sunkenFrame = FXHorizontalFrame.new(bottomFrame,
  FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
@stringVal = FXDataTarget.new("", nil, 0)
@translatedText = FXText.new(sunkenFrame, @stringVal, 

FXDataTarget::ID_VALUE,
TEXT_READONLY|LAYOUT_FILL_X|LAYOUT_FILL_Y)
end

def create
super
show(PLACEMENT_CURSOR)
end

def procAll(sender, sel, ptr)
@stringVal.value += “This is new text\n” # This doesn’t appear
<20-minutes-processing here>
end # until here. Why is
this ?

end

if FILE == $0
application = FXApp.new(“Test”, “Test”)
window = Update_test.new(application)
application.create
application.run
end

Graham Stokes wrote:

that I get nothing until procAll ends. Clearly I’ve missed a step with
setting up the messaging, but the documentation is persuading me that
there’s nothing more to do.

Can anybody tell me what’s wrong with the code below ? Why won’t the
text field show the text as soon as the data target is updated as the
documentation implies it will ? Other widgets behave in a similar
fashion with the exception of the progress bar which will update
immediately. Very peculiar. Any help appreciated.

I think your diagnosis is right. Your ruby code is never giving Fox a
chance to update the GUI. You can fix it by explicitly sharing time with
Fox:

def procAll(sender, sel, ptr)
@stringVal.value += “This is new text\n”
500.times do
getApp.runOneEvent
sleep 0.01 # or do some fraction of your processing
end
end

There’s still a little delay, but it’s probably acceptable.

You might want to do the runOneEvent calls in one ruby thread, and do
your non-GUI processing in another.

In some cases, you really want “as soon as” semantics, and in those a
good alternative to FXDataTarget is my FoxTails lib. See
FoxTails or search the fxruby-users list
archive.

Joel VanderWerf wrote:

I think your diagnosis is right. Your ruby code is never giving Fox a
chance to update the GUI. You can fix it by explicitly sharing time with
Fox:

def procAll(sender, sel, ptr)
@stringVal.value += “This is new text\n”
500.times do
getApp.runOneEvent
sleep 0.01 # or do some fraction of your processing
end
end

There’s still a little delay, but it’s probably acceptable.

You might want to do the runOneEvent calls in one ruby thread, and do
your non-GUI processing in another.

Joel, thanks a lot for pointing me in the right direction - this indeed
turns out to be the problem and event processing in a separate thread is
easy and elegant. How curious that none of the examples supplied pays
any attention to this requirement.

In some cases, you really want “as soon as” semantics, and in those a
good alternative to FXDataTarget is my FoxTails lib. See
FoxTails or search the fxruby-users list
archive.

I will check this out to see the benefits. Thanks again.

Best Regards,
Graham