[fxruby-users] FXText update within threads
Melton, Ryan
rmelton at ball.com
Wed Feb 15 10:53:05 EST 2012
You're not allowed to interact with the GUI from threads. You need to put any GUI function calls inside of a timeout handler so that they execute in the main thread.
Ryan
-----Original Message-----
From: fxruby-users-bounces at rubyforge.org [mailto:fxruby-users-bounces at rubyforge.org] On Behalf Of watobo
Sent: Wednesday, February 15, 2012 12:28 AM
To: fxruby-users at rubyforge.org
Subject: [fxruby-users] FXText update within threads
Hi fxruby-users,
I want to set the text (setText/appendText) of an FXText widget out of a
thread. As soon as the scroll bar appears in the widget the gui is not
responsive anymore. This behaviour only occurs under windows (Win7-64). Under
Linux it just works fine.
Using FXDataTarget is not possible because it produces a big delay on
updating the widget. Additionally, if I use an FXDataTarget it seems that all my other message handlers disapear.
Here's the sample code which triggers the behaviour:
-------------8<--------------------
#!/usr/bin/env ruby
require 'rubygems'
require 'fox16'
include Fox
class MyWorker
@@pool_mutex = Mutex.new
def subscribe(event, &callback)
(@event_dispatcher_listeners[event] ||= []) << callback
end
def notify(event, *args)
if @event_dispatcher_listeners[event]
@@pool_mutex.synchronize do
@event_dispatcher_listeners[event].each do |m|
m.call(*args) if m.respond_to? :call
end
end
end
end
def run
progress = {}
@total.times do |i|
Thread.new(i) { |ii|
msg = "#{@name}: #{ii}\n"
puts msg + " - running ..."
notify(:logger, msg)
sleep 1
puts msg + " - finished!"
}
end
end
def initialize(name, total = 100)
@event_dispatcher_listeners = {}
@total = total
@name = name
end
end
class MTTextTest < FXMainWindow
@@textMutex = Mutex.new
def initialize(app)
# Call base class initializer first
super(app, "Producer Test", :width => 800, :height => 600)
frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
@textbox = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_AUTOSCROLL)
showButton = FXButton.new(frame, "&Thread", :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT)
showButton.connect(SEL_COMMAND) do
# @textbox.hide
@tl = []
10.times do |x|
# print "\n* starting worker #{x}..."
name = "w#{x}"
worker = MyWorker.new(name, x*3)
worker.subscribe(:logger) { |msg|
begin
@@textMutex.synchronize do
@textbox.appendText( msg, false )
end
rescue => bang
puts bang
puts bang.backtrace
end
}
worker.run
end
# @textbox.appendText "ALL WORKERS STARTED !!!\n"
# @tl.each do |t| t.join; end
end
end
# Create and show the main window
def create
super # Create the windows
show(PLACEMENT_SCREEN) # Make the main window appear
end
end
if __FILE__ == $0
# Construct the application object
application = FXApp.new('Multi-Thread-Producer Test', 'FoxTest')
# Construct the main window
scribble = MTTextTest.new(application)
# Create the application
application.create
application.run
end
-------------8<--------------------
C:\Users\andy>ruby -e "require 'fox16'; puts \"Ruby: #{RUBY_VERSION}\nFox: #{Fox
.fxversion}\""
Ruby: 1.9.2
Fox: 1.6.44
Does anybody know what's wrong here?
Thanks,
Andy
_______________________________________________
fxruby-users mailing list
fxruby-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/fxruby-users
This message and any enclosures are intended only for the addressee. Please
notify the sender by email if you are not the intended recipient. If you are
not the intended recipient, you may not use, copy, disclose, or distribute this
message or its contents or enclosures to any other person and any such actions
may be unlawful. Ball reserves the right to monitor and review all messages
and enclosures sent to or from this email address.
More information about the fxruby-users
mailing list