Alex Ciarlillo
2008-Jan-16 16:41 UTC
Question about WxNotebook, threads, and GUI refreshing
I''m running into a problem I''ve had before with wxRuby where the GUI does not update while my App is processing some set of data. The fix for this I know is to put the data processing piece in a new thread and in the Wx::App code make a timer to pass the threads. This has always worked in the past, but now my problem is slightly more complex and I''m at a loss. Basically I am trying to put together a bunch of small reporting apps I''ve made into one single application using tabs to separate them. I''ve redesigned each of the other applications so that they each contain their own panel class and controller class (for doing the processing) then I have the main application which contains the Wx::App and Wx::Notebook and the notebook simply adds pages using instances of the panel classes I created. So the problem (I assume) is that I''m not setting up the thread switching properly for use with a Wx::Notebook. Here is the main app code: --- MultiTool.rb --- require ''wx'' require ''wx_sugar/all'' require ''panels/all.rb'' class MainNB < Wx::Notebook def initialize(parent, id) super(parent, id, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::NB_TOP) fpar_page = add_page(FPARPanel.new(self), "Acct. Report", true, 0) gsbis_page = add_page(GSBISPanel.new(self), "Inv. Scan", true, 0) mpa_page = add_page(MPAPanel.new(self), "Product Addition", true, 0) msrpc_page = add_page(MSRPCPanel.new(self), "SRP Change", true, 0) payparse_page = add_page(PayParsePanel.new(self), "Payroll Report", true, 0) set_selection(0) end end class MyApp < Wx::App def on_init frame = Wx::Frame.new(nil, :size => Wx::Size.new(686, 303), :title => "MultiTool") notebook = MainNB.new(frame, 0) t = Wx::Timer.new(self, 55) evt_timer(55) { Thread.pass } t.start(20) frame.show end end MyApp.new.main_loop --- END --- So that is where I create the timer and pass the thread... then the thread is actually created when a button is pressed on one of the panels in the notebook. The end result is that whatever is in the new thread just never executes. I''m trying to break this up into a larger but easily maintainable set of applications which is why I have all the files separated out in the way I do, but I''m really unsure of how this affecting the execution of the code. The code for the panels is all pretty lengthy and in the middle of being cleaned up and re-written, but its basically in the form: --- example panel --- class GSBISPanel < Wx::Panel def initialize(*args) super(*args) # bunch of crap in a grid # button that starts data processing add(Wx::Button[:label => ''Run'']) do |@b_run| listen(:button, @b_run, :run) end end def run t = Thread.new { #process a bunch of data (this never runs)} end end --- END example --- I hope I am explaining this thoroughly and clearly. If anyone has some pointers or ideas of how to approach this please let me know. thanks, -alex
Alex Fenton
2008-Jan-16 22:41 UTC
[wxruby-users] Question about WxNotebook, threads, and GUI refreshing
Hi Alex Alex Ciarlillo wrote:> I''m running into a problem I''ve had before with wxRuby where the GUI > does not update while my App is processing some set of data. The fix for > this I know is to put the data processing piece in a new thread and in > the Wx::App code make a timer to pass the threads. This has always > worked in the past, but now my problem is slightly more complex and I''m > at a loss. >I can''t see anything wrong with the way you''ve set things out. As the etc/threaded.rb sample shows, there should be no problem with having multiple ruby 1.8 threads running in the background of a wxRuby application. Perhaps ensure that you set abort_on_exception = true for each of the child threads. I''ve sometimes been puzzled that a thread''s not running, only to find that there''s some bug in the thread''s code which means it''s crashed and stopped, but silently. Incidentally, as of wxRuby 1.9.4, you''ll be able to use a slightly neater notation to pass control among ruby threads, eg: Wx::Timer.every(50) { Thread.pass } to rotate every 50ms> Basically I am trying to put together a bunch of small reporting apps > I''ve made into one single application using tabs to separate them.THere''s probably different ways to design this. Depending on what the child notebooks are doing, you could run two timers, one to make ruby''s threads run, and another to check a queue for updates to the GUI. Then the child threads could add updates to this queue. alex
Apparently Analagous Threads
- [829] trunk/wxruby2/samples/bigdemo/wxNotebook.rbw: Fix icon path for notebook tab (was crashing linux bug 6632)
- Patch to wxNotebook.rbw
- [1053] trunk/wxruby2/samples: Change references to assign_image_list methods to set_image_list in samples
- [1052] trunk/wxruby2: Remove unwanted Notebook#assign_image_list method, update docs
- [LLVMdev] CMake builds clang.