問(wèn)題描述
我的客戶端應(yīng)用程序使用 Kivy
GUI(Kivy 有自己的事件循環(huán))并使用帶有 Tornado
的 WebSocket 協(xié)議連接到服務(wù)器(Tornado 也有一個(gè)事件循環(huán)).這就是連接部分是異步的原因.
我希望用戶在 Tornado 客戶端運(yùn)行無(wú)限異步循環(huán)以偵聽(tīng)服務(wù)器消息時(shí)與 UI 交互.
My client application uses a Kivy
GUI (Kivy has its own event loop) and connects to the server using the WebSocket protocol with Tornado
(Tornado also has an event loop). That's why the connection part is asynchronous.
I want the user to interact with the UI while a Tornado client is running an infinite asynchronous loop of listening for server messages.
以下是一些示例代碼:
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()
圖形界面
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 的事件循環(huán)已經(jīng)開(kāi)始較早,它已經(jīng)接管了程序流程,現(xiàn)在沒(méi)有出現(xiàn) GUI 窗口.
我執(zhí)行 GUI 文件,在 RequestSender().run()
之后執(zhí)行掛起,因此 build
永遠(yuǎn)不會(huì)返回.
Apparently, since the Tornado's event loop has started earlier, it has taken over the program flow and now no GUI window appears.
I execute the GUI file and the execution hangs after the RequestSender().run()
, so build
never returns.
搜索此案例幾乎沒(méi)有提供任何信息,除了 thisGoogle 網(wǎng)上論壇帖子.Kivy 的文檔僅提及 Twisted.
Searching on this case provided little to no information, except for this Google Groups post. Kivy's documentation only mentions Twisted.
我嘗試將 Kivy 事件循環(huán)置于從屬模式并從 Tornado 的事件循環(huán)運(yùn)行 GUI 更新,但這不起作用,因?yàn)轱@然 Kivy 的事件循環(huán)的調(diào)用 EventLoop.idle()
不是足以保持 GUI 應(yīng)用程序運(yùn)行.
I tried putting the Kivy event loop into slave mode and running GUI updates from Tornado's event loop, but that didn't work because apparently a call EventLoop.idle()
of Kivy's event loop isn't enough to keep the GUI application running.
這里還能做什么?
推薦答案
我發(fā)現(xiàn)這個(gè)問(wèn)題試圖做同樣的事情,并選擇了兩個(gè)單獨(dú)的進(jìn)程;一個(gè) Kivy GUI 和一個(gè) Tornado(在我的例子中是服務(wù)器).我有兩個(gè)使用 multiprocessing.connection
進(jìn)行通信,如 this SO answer 中所述
I found this question trying to do the same thing, and opted for two separate processes instead; one Kivy GUI and one Tornado (Server, in my case). I have the two communicate using multiprocessing.connection
as explained well in this SO answer
如果您要在兩者之間傳遞大量而復(fù)雜的數(shù)據(jù),這可能不太理想,但對(duì)于簡(jiǎn)單的消息來(lái)說(shuō)效果很好.您還可以在沒(méi)有 UI 的情況下運(yùn)行,并在單獨(dú)的計(jì)算機(jī)上運(yùn)行 UI.
If you have large and complex data to pass between the two, perhaps this is less than ideal, but for simple messages it works well. You also have the advantage of running without the UI, and running the UI on a separate machine.
這篇關(guān)于如何在 Kivy GUI 旁邊運(yùn)行 Tornado 事件循環(huán)?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!