On macOS X, Cocoa uses an event loop to dispatch events (NSRunLoop
, which is a wrapper around CFRunLoop
).
Python's asyncio module uses an event loop too to handle asynchronous events. On macOS X, it's based on kqueue.
A thread can only use a single event loop, that's why it's not possible to use both Cocoa and asyncio on the same thread. This module implements an asyncio compatible event loop on top of CFRunLoop. Thus it's possible to use Cocoa in conjunction with asyncio.
It uses internally PyObjC's runEventLoop
or runConsoleEventLoop
Here is an example video of a simple Cocoa based GUI using asyncio
and async
/await
to handle subprocesses and network calls:
The corresponding code is here: tests/gui/guidemo.py
Setup:
loop = CoreFoundationEventLoop()
asyncio.set_event_loop(loop)
try:
loop.run_forever()
finally:
loop.close()
CoreFoundationEventLoop
's constructor's first argument is a boolean. True
for a console app, False
(default) for a GUI app.
Additionnal arguments are then passed to PyObjCTools.AppHelper.runConsoleEventLoop
or PyObjCTools.AppHelper.runEventLoop
This module also provides a selector implementation based on CFRunLoop. But his selector isn't compatible with Cocoa GUIs
$ pip3 install corefoundationasyncio
This module depends on pyobjc
Report issues here
Pull-requests welcome !
This software is licensed under the MIT license