[fxruby-users] FXText update within threads

Andreas Schmidt watobo at siberas.de
Wed Feb 15 15:18:44 EST 2012


Hi Ryan,

why not? Even in the groupbox.rb example a thread is used to update the
clock. I've often used threads to control widgets and it worked all the
time with Ruby 1.8. In Ruby 1.9 a lot of the thread managment changed,
you can use threads to control FXTables, FXLabel or FXProgressBar
without any problems. But I experienced this problem with FXText widget
and I don't understand where this problem lies. Is it a problem of
FXRuby or of the Fox-Toolkit?

thanks,
-andy


 Am 15.02.2012 16:53, schrieb Melton, Ryan:
> 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.
> _______________________________________________
> fxruby-users mailing list
> fxruby-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/fxruby-users



More information about the fxruby-users mailing list