如何在Kivy GUI旁边运行Tornado事件循环?

时间:2016-12-10 11:58:23

标签: python kivy tornado python-3.5 event-loop

我的客户端应用程序使用Kivy GUI(Kivy有自己的事件循环)并使用带有Tornado的WebSocket协议连接到服务器(Tornado也有一个事件循环)。这就是连接部分异步的原因 我希望用户在Tornado客户端运行无限的异步循环监听服务器消息时与UI进行交互。

以下是一些示例代码:
client_test.py

from tornado.ioloop import IOLoop
from tornado.websocket import websocket_connect

class RequestSender:
    url = 'server url here (no scheme)'

    async def _connect(self):
        self.conn = await websocket_connect('wss://' + self.url, io_loop=self.ioloop)
        self.ioloop.add_callback(self._listen)

    async def _listen(self):
        while True:
            print(await self.conn.read_message())

    def __init__(self):
        self.ioloop = IOLoop.current()
        self.ioloop.add_callback(self._connect)

    def run(self):
        self.ioloop.start()

GUI

from kivy.app import App
from kivy.uix.label import Label
from client_test import RequestSender

class TestApp(App):
    def build(self):
        RequestSender().run()
        return Label(text = "hello")

TestApp().run()

显然,由于Tornado的事件循环已经开始,它已经接管了程序流程,现在没有出现GUI窗口。
我执行GUI文件,执行在RequestSender().run()之后挂起,因此build永远不会返回。

除了this Google Groups post之外,搜索此案例几乎没有提供任何信息。 Kivy的文档仅提及Twisted

我尝试将Kivy事件循环置于从属模式并从Tornado的事件循环中运行GUI更新,但这不起作用,因为显然是对Kivy事件的调用EventLoop.idle()循环不足以使GUI应用程序继续运行。

这里还能做些什么?

1 个答案:

答案 0 :(得分:0)

我发现这个问题试图做同样的事情,而选择了两个独立的过程;一个Kivy GUI和一个Tornado(服务器,在我的情况下)。如this SO answer

中所述,我使用multiprocessing.connection进行了两次沟通

如果要在两者之间传递大而复杂的数据,可能这不太理想,但对于简单的消息,它可以很好地工作。您还可以在没有UI的情况下运行,并在单独的计算机上运行UI。