我正在使用PyQt5和Quamash从TCP服务器接收消息并将其显示在QTextBrowser中。
Fisrt, 如果(useQEventLoop = False,showGui = False)表示使用loop = asyncio.get_event_loop()并且不显示QMainWindow,则在TCP服务器关闭时,它仍然可以尝试继续使用TCP服务器重新连接到服务器打开。
Fri Jun 29 10:06:30 2018
Try to connect after 1 seconds...
Fri Jun 29 10:06:32 2018
Try to connect after 1 seconds...
Fri Jun 29 10:06:34 2018
Try to connect after 1 seconds...
Fri Jun 29 10:06:36 2018
然后, 如果(useQEventLoop = True,showGui = False),则在TCP服务器关闭时,它将引发以下无法捕获的错误,并停止重新连接到TCP服务器。
Fri Jun 29 10:07:37 2018
Event callback failed
Traceback (most recent call last):
File "D:\Zibo\Documents\SRC\workspace\QHub\venv\lib\site-packages\quamash\_windows.py", line 42, in _process_events
value = callback(transferred, key, ov)
File "D:\Python35\Lib\asyncio\windows_events.py", line 509, in finish_connect
ov.getresult()
ConnectionRefusedError: [WinError 1225]
最后, 如果(useQEventLoop = True,showGui = True)甚至先打开TCP服务器,套接字也会从TCP服务器回显该消息,但是它将停止使用新消息更新QTextBrowser。 如果有变化:
asyncio.run_coroutine_threadsafe(mw.update(), loop)
收件人:
asyncio.ensure_future(mw.update())
将引发附加异常,并且QTextBrowser中仍然没有消息更新。
1530238157.9816725
Fri Jun 29 10:09:17 2018
Task exception was never retrieved
future: <Task finished coro=<MainWindow.update() done, defined at D:\Zibo\Documents\SRC\workspace\QHub\vis\visstarter2.py:75> exception=RuntimeError('Task <Task pending coro=<MainWindow.update() running at D:\\Zibo\\Documents\\SRC\\workspace\\QHub\\vis\\visstarter2.py:78>> got Future <Future pending> attached to a different loop',)>
Traceback (most recent call last):
File "D:\Python35\Lib\asyncio\tasks.py", line 242, in _step
result = coro.throw(exc)
File "D:\Zibo\Documents\SRC\workspace\QHub\vis\visstarter2.py", line 78, in update
msg = await vq.get()
File "D:\Python35\Lib\asyncio\queues.py", line 167, in get
yield from getter
File "D:\Python35\Lib\asyncio\futures.py", line 381, in __iter__
yield self # This tells Task to wait for completion.
RuntimeError: Task <Task pending coro=<MainWindow.update() running at D:\Zibo\Documents\SRC\workspace\QHub\vis\visstarter2.py:78>> got Future <Future pending> attached to a different loop
任何提示或信息将不胜感激。
代码如下:
import sys
import time
import asyncio
import logging
from quamash import QEventLoop
from PyQt5.QtWidgets import QApplication
logger = logging.getLogger(__name__)
async def visSender(w, q):
while True:
if q.qsize() > 0:
msg = await q.get()
if msg:
try:
logger.debug(msg)
w.write(msg)
await w.drain()
except ConnectionResetError:
break
else:
await asyncio.sleep(0.01)
async def startVis(vis_loop, vhost, vport, vq, qq):
vwriter = None
vsent = None
while True:
print(time.ctime())
try:
vreader, vwriter = await asyncio.open_connection(host=vhost, port=vport, loop=vis_loop)
vsent = vis_loop.create_task(visSender(vwriter, vq))
asyncio.ensure_future(vsent)
#asyncio.run_coroutine_threadsafe(visSender(vwriter, qq), vis_loop)
async for msg in vreader:
await vq.put(msg)
print(msg)
except Exception as e:
#logger.exception(e)
print("Try to connect after 1 seconds...")
if vsent:
vsent.cancel()
if vwriter:
vwriter.close()
vwriter = None
vreader = None
await asyncio.sleep(1)
from PyQt5.QtWidgets import QMainWindow, QTextBrowser
class MainWindow(QMainWindow):
def __init__(self, vq):
QMainWindow.__init__(self)
self.vq = vq
self.centralwidget = QTextBrowser(self)
self.setCentralWidget(self.centralwidget)
self.centralwidget.append("Starting...")
async def update(self):
while True:
print(time.time())
msg = await vq.get()
self.centralwidget.append(msg.decode())
await asyncio.sleep(0.01)
if __name__ == '__main__':
vhost = "127.0.0.1"
vport = 8848
logger.setLevel(logging.DEBUG)
vq = asyncio.Queue()
qq = asyncio.Queue()
useQEventLoop = True
showGui = False
if useQEventLoop:
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop) # NEW must set the event loop
if showGui:
mw = MainWindow(vq)
mw.show()
#asyncio.run_coroutine_threadsafe(mw.update(), loop)
asyncio.ensure_future(mw.update())
else:
loop = asyncio.get_event_loop()
asyncio.run_coroutine_threadsafe(startVis(loop, vhost, vport, vq, qq), loop)
try:
loop.run_forever()
except Exception as e:
print(e)
pending = asyncio.Task.all_tasks(loop)
for task in pending:
task.cancel()
finally:
loop.close()