2016-12-10 19 views
3

我的客戶端應用程序使用一個Kivy GUI(Kivy有它自己的事件循環)並使用WebSocket協議與Tornado(Tornado也有一個事件循環)連接到服務器。這就是連接部分是異步的原因。
我希望用戶在Tornado客戶端運行無限次的服務器消息偵聽循環時與UI進行交互。如何與Kivy GUI一起運行Tornado事件循環?

下面是一些示例代碼:
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() 

顯然,因爲龍捲風的事件循環已經起步較早,它已經接管程序流程,現在沒有GUI窗口出現。
我執行GUI文件,執行掛起後RequestSender().run(),所以build永遠不會返回。

在這種情況下搜索幾乎沒有信息,除了this Google Groups post。 Kivy的文檔只提到Twisted

我試圖將Kivy事件循環放入從屬模式並從Tornado的事件循環中運行GUI更新,但這並不奏效,因爲顯然Kivy事件循環的調用EventLoop.idle()不足以保持GUI應用程序運行。

還有什麼可以在這裏做?

+0

我認爲扭曲的方法是讓Kivy的eventloop驅動Twisted的eventloop。也許你可以用Tornado實現同樣的目標。 – inclement

+0

@inclement不清楚Twisted事件循環是如何被驅動的,因爲它是一個專門用於Twisted的包。我嘗試了一種向後的方法:讓Kivy事件循環作爲從屬和Tornado事件循環來在每次迭代中調用'EventLoop.idle()'。該窗口成功加載,但然後應用程序凍結。編輯中的更多細節 – Leva7

+0

我認爲用兩個單獨的線程運行兩個事件循環可能比嘗試將它們同時集成更容易處理。 – Nykakin

回答

0

我發現這個問題試圖做同樣的事情,而選擇了兩個單獨的進程,而不是;一個Kivy GUI和一個Tornado(服務器,就我而言)。我有兩個之間採用multiprocessing.connectionthis SO answer

很好地解釋如果你有龐大而複雜的數據,在二者之間傳遞,這也許是不太理想,但對於簡單的郵件它工作得很好。您還可以在不使用UI的情況下運行該優勢,並在另一臺計算機上運行UI。