В моем клиентском приложении используется графический интерфейс Kivy
(у Kivy есть собственный цикл событий) и подключается к серверу с использованием протокола WebSocket с Tornado
(у Tornado также есть цикл событий). Вот почему соединение является асинхронным.
Я хочу, чтобы пользователь взаимодействовал с пользовательским интерфейсом, а клиент Tornado запускал бесконечный асинхронный цикл прослушивания сообщений сервера.Как запустить цикл событий Tornado вместе с графическим интерфейсом Kivy?
Вот пример кода:
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, но это не сработало, потому что, по-видимому, вызов цикла EventLoop.idle()
цикла событий Kivy недостаточен для работы приложения GUI.
Что еще можно сделать здесь?
Я думаю, что подход, сделанный с извращенным, состоит в том, чтобы включить event -oo приключений Kivy в Twisted's eventloop. Возможно, с Торнадо можно добиться того же. – inclement
@inclement неясно, как цикл Twisted event управляется, поскольку это пакет специально для Twisted. Вместо этого я попробовал обратный подход: нужно, чтобы цикл событий Kivy запускался как ведомый и цикл событий Tornado для вызова 'EventLoop.idle()' на каждой итерации. Окно успешно загружается, но затем приложение зависает. Подробнее в редакторе – Leva7
Я думаю, что запуск двух циклов событий с двумя отдельными потоками может быть намного проще в обработке, чем попытка их интеграции. – Nykakin