Okey的人质疑asyncio和Gtk +。如何在Gtk.main循环中运行以下代码?我搜索了例如,但找不到任何东西。
#!/usr/bin/python3.4
import asyncio
@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()
Server=asyncio.start_server(client_connected_handler, 'localhost', 2222)
server=loop.run_until_complete(Server)
loop.run_forever()
哦,我应该把我的经验写在gbulb上。首先,我使用pip3搜索了它。我找到它并尝试安装它,但由于链接错误而失败了(我正在使用超级用户进行安装)。接下来,我从他们的存储库中下载了它并安装了它。我得到了这个示例,我运行了它并且由于缺少核心模块中的参数而遇到了一些错误。我真的不知道是什么错误导致我从另一台PC上编写此错误更新是尽快。如果有人可以测试我也将不胜感激。
截至2020年,gbulb库似乎已不再维护。希望集成asyncio和GTK的任何人都应该只考虑答案的第二部分(显示asyncio在专用线程中运行)或查看asyncio-glib
,它使用比gbulb更为简约和可靠的方法来集成asyncio和GTK。
原始答案如下。
该gbulb
库旨在在PEP 3156指定的asyncio事件循环与GLib主循环实现之间提供连接器。但是,(此问题后来在上游得到解决。)gbulb
Python 3.4附带的asyncio的当前主节点已损坏。要解决此问题,您可以签出此fork而不是master。
对于工作正常的灯泡,修改示例以接受传入连接并运行GTK并不容易:
#!/usr/bin/python3
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事件循环:
#!/usr/bin/python3
import asyncio, threading
from gi.repository import Gtk
async def client_connected_handler(client_reader, client_writer):
# ... unchanged ...
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线程之间进行通信。这意味着使用loop.call_soon_threadsafe
或asyncio.run_coroutine_threadsafe
将事物从GTK提交给asyncio,GLib.idle_add
并将事物从asyncio提交给GTK。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句