Jonathan Stoppani <jonat...@garetjax.info> writes: > Hi Ronald, > thanks for the response. I already saw the examples on the pyobjc > website, but they (two) are all using Cocoa to do some GUI related > work. > > I don't have a gui and I use the console loop instead. > > I'm now trying to use the code attached to this ticket and it seems to > work, but I have to test it a little more.
Not sure which ticket is being referenced but which Twisted reactor are you using? I've had very good luck with the threadedselect reactor, which shouldn't care if your main loop is a GUI or not. You interleave with AppHelper.callAfter, which I think should work fine with both runConsoleEventLoopas well as the GUI runEventLoop For my part, any OSX console apps I've had to do could just be pure Twisted, with no need to integrate with an NSRunLoop, so I'm not that familiar with how you best track startup/shutdown in those cases. But fundamentally, you install the threadedselect reactor (do that before any other code uses "from twisted.internet import reactor"), then use "reactor.interleave(AppHelper.callAfter)" to tie the reactor in to the normal event loop. In the Cocoa/NSApplication scenario, I use the applicationDidFinishLaunching notification to trigger this. During shutdown, wait for the reactor to perform its shutdown so it can close things down cleanly, using a reactor trigger to finalize the event loop with "AppHelper.stopEventLoop". Again, presumably you'll have some way to determine when this is appropriate in your console event loop - in a Cocoa/NSApplication scenario, I use the applicationShouldTerminate notification. (I've tended to install the trigger right at that point too, although it could also be done earlier) Here's a trivial example, where I kluge a startup event. Presumably the reason you are using runConsoleEventLoop is to use other native event/input sources based operations, so you might have a more logical place or event to identify when to start the twisted integration - all that's required is that it be done after the main event loop is running. If not, while I chose a 1s startup delay in this example, it was mostly to see the difference in timestamps - you can make the initial callLater a timeout of 0, and it'll just run as soon as the event loop gets started. This example also just terminates after two Twisted-based delayed events, but that would also be determined by your own application: """Test console event loop app with Twisted threadedselect reactor""" import time from PyObjCTools import AppHelper from twisted.internet._threadedselect import install reactor = install() class Main(object): def startup(self): print time.ctime(), 'Main starting' reactor.callLater(1, self.callback) reactor.interleave(AppHelper.callAfter) def terminate(self): print time.ctime(), 'Shutting down reactor' reactor.addSystemEventTrigger('after', 'shutdown', AppHelper.stopEventLoop) reactor.stop() def callback(self): print time.ctime(), 'I was called by the reactor' reactor.callLater(1, self.terminate) if __name__ == "__main__": main = Main() AppHelper.callLater(1, main.startup) print time.ctime(), 'Starting Event Loop' AppHelper.runConsoleEventLoop() print time.ctime(), 'Terminating' When running, this produces: Sun Nov 1 19:53:16 2009 Starting Event Loop Sun Nov 1 19:53:17 2009 Main starting Sun Nov 1 19:53:18 2009 I was called by the reactor Sun Nov 1 19:53:19 2009 Shutting down reactor Sun Nov 1 19:53:19 2009 Terminating -- David _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python