rubywindows-10tcltk-toolkittcltk

Change Ruby TK menu entry state while a variable is changing too?


Let's assume i have this menu:

menubar = TkMenu.new(win)
win['menu'] = menubar

edit = TkMenu.new(menubar)

menubar.add :cascade, :menu => edit, :label => 'Edit'

edit.add(:command, :label => 'Delete')

And i want to change the "edit" entry state when a variable is changing too.

I tried this,

def update_menu(edit)
  Thread.new {
   loop {

     if $variable == nil
      edit.entryconfigure 'Delete', :state => "disabled"
     else
      edit.entryconfigure 'Delete', :state => "normal"
     end

     sleep 0.1

   }
  }
end 

And it actually works but the tk menu will flash for every tick of the loop.
I'm messing up something or is there a better way for loops in TK? It seems like a bug...

I'm on Windows 10 and this is my ruby version:
ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]


Solution

  • I found a workaround to avoid those flashes on menus.

    I used while loops doing nothing to "pause" the thread, then when their condition become true, they will end so the edit.entryconfigure code will execute only once, changing the menu entry state. All this closed in a loop.

    This the updated code:

    def update_menu(edit)
     Thread.new {
      loop {
    
       while $variable == nil; sleep 0.1; end
       edit.entryconfigure 'Delete', :state => "normal"
    
       while $variable != nil; sleep 0.1; end
       edit.entryconfigure 'Delete', :state => "disabled"
    
       sleep 0.1
      }
     }
    end
    

    Now the menus looks good and no flashes there.