截至2020年,gbulb库似乎
未维护。任何希望集成asyncio和GTK的人应该只考虑答案的第二部分(展示在专用线程中运行的asyncio),或者看一下
asyncio-glib
,它使用比gbulb更简洁且更稳健的方法集成了asyncio和GTK。
下面是原始回答。
"The
gbulb
library is designed to connect the asyncio event loop specified by PEP 3156 with the GLib main loop implementation.
However, the current version of gbulb
is incompatible with asyncio in Python 3.4. To solve this problem, you can use this fork instead of the original version. (The issue has been fixed in the latest version.)
If you have a working gbulb, it is easy to modify your code to accept incoming connections and run GTK:"
import gi
gi.require_version("Gtk", "3.0")
import asyncio, gbulb
from gi.repository import Gtk
asyncio.set_event_loop_policy(gbulb.GLibEventLoopPolicy())
@asyncio.coroutine
def client_connected_handler(client_reader, client_writer):
print("Connection received!")
client_writer.write(b'Hello')
while True:
data = yield from client_reader.read(8192)
if not data:
break
if 'EXIT' in data.decode():
print("Closing server")
break
print(data)
client_writer.write(data)
print('Server is closed')
loop = asyncio.get_event_loop()
loop.run_until_complete(
asyncio.start_server(client_connected_handler, 'localhost', 2222))
w = Gtk.Window()
w.add(Gtk.Label('hey!'))
w.connect('destroy', Gtk.main_quit)
w.show_all()
loop.run_forever()
另一种可能性是在不同的线程中运行asyncio事件循环:
import asyncio, threading
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
async def client_connected_handler(client_reader, client_writer):
def run_asyncio():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(
asyncio.start_server(client_connected_handler, 'localhost', 2222))
loop.run_forever()
threading.Thread(target=run_asyncio).start()
w = Gtk.Window()
w.add(Gtk.Label('hey!'))
w.connect('destroy', Gtk.main_quit)
w.show_all()
Gtk.main()
这种方法的优点是完全不需要使用
gbulb
(目前尚不清楚
gbulb
在生产环境中的测试情况如何)。但是需要注意,必须使用线程安全的函数在GUI(主)线程和asyncio线程之间进行通信。这意味着从GTK向asyncio提交任务时要使用
loop.call_soon_threadsafe
或
asyncio.run_coroutine_threadsafe
,而向GTK提交任务时要使用
GLib.idle_add
。
pip3 install gbulb
可以正常工作,并且在 Github 的示例部分中的计数器演示可以顺利运行。 - jcoppens