def do_in_mainthread(f, wait=True): from AppKit import NSThread if NSThread.isMainThread(): return f() try: NSObject = objc.lookUpClass("NSObject") class PyAsyncCallHelper(NSObject): def initWithArgs_(self, f): self.f = f self.ret = None self.exc = None return self def call_(self, o): try: self.ret = self.f() except (KeyboardInterrupt,SystemExit) as exc: self.exc = exc except: print "Exception in PyAsyncCallHelper call" sys.excepthook(*sys.exc_info()) except: PyAsyncCallHelper = objc.lookUpClass("PyAsyncCallHelper") # already defined earlier helper = PyAsyncCallHelper.alloc().initWithArgs_(f) helper.performSelectorOnMainThread_withObject_waitUntilDone_(helper.call_, None, wait) if wait and helper.exc: raise helper.exc return helper.ret