[fxruby-users] Getting fewer paints per second than I expected

Joel VanderWerf vjoel at path.berkeley.edu
Sun Nov 5 18:22:06 EST 2006

Wayne Conrad wrote:
> I've got a program that puts 20 text labels in the main window.  Each
> label updates itself to a global counter on SEL_UPDATE.  The counter
> increments 10 times a second.
> To my surprise, the labels skip counter updates.  I expected to see
> each label painting a new timer value 10 times per second.  Instead,
> each label paints about 3 times per second.  CPU is about 100% idle
> when the program is running.
> Have I made a newbie mistake?  Is this a question for the regular Fox
> list?

I verified your observations with fox16 (fxruby): updates skip and cpu < 
   1%. In addition I checked that the timer is really called 10 times 
per second (it turns out to be between 9 and 10 times per second, 
actually, probably due to the time it takes to re-register the timer).

It may be that using SEL_UPDATE works better in pure fox than in fxruby, 
but in my experience it's better to take control of the updates yourself 
if you want them done promptly.  You can do this by setting up an 
observer relationship and using that to set the label text when the 
variable changes.

This is part of the reason I wrote the observable[1] and foxtails[2] 
libraries. Here's a modification of your code that updates about 10 
times per second. I had to use a text field in this example instead of a 
label because I had never thought of making label text connect to a 
variable, but it would not be hard to do. It still runs with <1% cpu, 
though probably a bit more than using SEL_UPDATE. FoxTails won't scale 
up to huge numbers of widgets as well as pure fox, of course, because 
(a) it has an extra layer of ruby code on top of fxruby and (b) is it 
eager rather than lazy about updates. (I feel that the laziness of 
updates in fxruby, especially menu items, is a serious problem.)

   require 'foxtails'

   include Fox
   include FoxTails

   class Main
     extend Observable

     observable :i

     def initialize
       self.i = 0

     def run
       @app = FXApp.new
       main = FXMainWindow.new(@app, File.basename(__FILE__))
       FXButton.new(main, "&Quit") do |button|
         button.layoutHints = LAYOUT_CENTER_X
         button.connect(SEL_COMMAND) do
       20.times do
         FTTextField.new(main, 10, self, :i)


     def start_timer
       @app.addTimeout(100, method(:timer))

     def timer(sender, sel, data)
       self.i += 1


   Main.new.run if $0 == __FILE__

That example didn't do any formatting, but there is a #field method that 
lets you use various %-escapes to do formatting and also to line things 
up using a FXMartix, perform validation, group radio buttons, add check 
buttons, and so on. These are all connected (in both directions) to ruby 
attrs using the observable mechanism.

In this case, just add your fields using the following code instead of 
the above:

       main.extend FTField
         # normally, you define a window class and include FTField

       20.times do
         main.field "current value is %04d", [self, :i]

The static text "current value os" is displayed as a label, and the 
dynamic text is displayed in a text field (but it could be a label with 
a little work).

Check out foxtails/examples/fields.rb for more.

[1] http://raa.ruby-lang.org/project/observable/
[2] http://raa.ruby-lang.org/project/foxtails/

       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

More information about the fxruby-users mailing list