From: Gregory C. <gr...@in...> - 2009-04-05 18:12:18
|
Hi Arcadio, If it's only a progress bar and log (and the GUI doesn't need to receive user input while the process is running) then you have another option. Create an ib_outlet for the view containing your progress message and progress bar (I called mine @progressView), then when you make changes to the progress bar, call displayIfNeeded on the view. Example: @progressIndicator.incrementBy(1) @progressView.displayIfNeeded If the contents of the view have changed, this forces it to "refresh" allowing you to have a working progress bar without needing a thread. (If you don't have a progress message that needs updating then you can simply call @progressIndicator.displayIfNeeded to update just the progress bar.) Greg > Hi Allison, > > thank you for the detailed explanation. > > From what I see you propose to run the GUI in a separate process, > which makes a lot of sense in order to avoid the global interpreter > lock. > > Answering your questions, my app is conceptually very simple. It's a > batch process. I'd prefer to launch the GUI from the command line. The > GUI will be basically a progress bar and a tree capturing the > different details of the execution (sort of a log). > > Moreover, I'd prefer to use method calls for communicating with the > GUI, that's why I was asking about how to instantiate a native thread > from Ruby using RubyCocoa. Let's see if somebody knows how to do this. > > If not, I'll do what you propose. The interface between the program > and the GUI is pretty simple. Probably a smart way of communicating > with the GUI is to use DrB (Distributed Ruby). You get all the > marshalling for free. It's roughly equivalent to RMI or RPC. > > -Arcadio > >> Hi Arcadio, >> >> OK, so you want a progress bar for your console-based app, is that >> right? >> >> A couple of questions: >> >> 1) Do you want to launch the app from the command line, or by >> clicking >> on the app icon in the finder? >> 2) is the console-based app interactive (does it take any input)? >> 3) How are you planning on communicating between the GUI and the app? >> Method calls? Communicating using stdin/stdout? >> >> Based on what you've said so far, I would suggest launching your UI >> app from the Finder, then in that app, fork, and launch your command >> line app in the child process. Make your command line app set up a >> server socket on a port that you have chosen. All input/output is >> directed to the socket created during the accept on the server >> socket. >> Then, in the parent process, start trying to connect to the server >> socket your command line app sets up. Once it succeeds, your UI app, >> and the command line app can communicate, whilst running in seperate >> processes. If you're really bored, you can even move ruby objects >> between the two, by marshalling them using YAML etc. >> >> It's a bit of a messy solution, but it has a couple of advantages: >> 1) It actually works (I've done this before), which, when it comes to >> simultaneous execution and Ruby, is no mean feat. >> 2) It leaves your original app as a standalone console app, so you >> can >> continue to use it as you have up until now. >> >> Anyhow, someone else may know of a cleaner way of achieving this, but >> I for one have never found another way that didn't fall foul of the >> global interpreter lock. >> >> Hope that helps. >> >> Alli >> >> >> Le 5 avr. 09 à 11:47, Arcadio Rubio García a écrit : >> >>> Hi all, >>> >>> I'm trying to build a very simple GUI for my Ruby application using >>> Cocoa. I have no experience with Cocoa or ObjC, so that might be >>> part >>> of the problem. >>> >>> Anyway, I have a Ruby text application and I would like to add this >>> GUI as an observer. So far I have other observers that for instance >>> write a log to a file, but none of them are graphical. >>> >>> My problem is that I need to run the GUI in another thread since >>> when >>> I start it, the call to app.run (in the code below) never returns. >>> As >>> far as I know, I cannot use Ruby (green) threads. >>> >>> Note that due to the design my project, I cannot invert control and >>> run my application within the thread created by Cocoa. Also, my code >>> is not (yet) compatible with Ruby 1.9, so I have to stick to 1.8. >>> >>> Can anyone point how to execute app.run in another thread in the >>> code >>> shown below. I've tried using >>> NSThread.detachNewThreadSelector_toTarget_withObject but haven't >>> been >>> successful. >>> >>> Thanks! >>> >>> >>> require 'osx/cocoa' >>> include OSX >>> >>> >>> class AppDelegate < NSObject >>> def init >>> frame = [200.0, 300.0, 250.0, 100.0] >>> @win = >>> NSWindow.alloc.initWithContentRect_styleMask_backing_defer(frame, >>> >>> 15, 2, 0) >>> @win.setTitle 'Test' >>> @win.setLevel 0 >>> @bar = NSProgressIndicator.alloc.initWithFrame [10.0, 10.0, 80.0, >>> 80.0] >>> @win.contentView.addSubview(@bar) >>> @bar.setIndeterminate(false) >>> @win.display >>> @win.orderFrontRegardless >>> end >>> >>> def step >>> @bar.incrementBy(20) >>> end >>> end >>> >>> >>> app = NSApplication.sharedApplication >>> app.setDelegate(AppDelegate.alloc.init) >>> app.run >>> >>> >>> ------------------------------------------------------------------------------ >>> _______________________________________________ >>> Rubycocoa-talk mailing list >>> Rub...@li... >>> https://lists.sourceforge.net/lists/listinfo/rubycocoa-talk >> >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> Rubycocoa-talk mailing list >> Rub...@li... >> https://lists.sourceforge.net/lists/listinfo/rubycocoa-talk > > > ------------------------------------------------------------------------------ > _______________________________________________ > Rubycocoa-talk mailing list > Rub...@li... > https://lists.sourceforge.net/lists/listinfo/rubycocoa-talk |