【发布时间】:2021-04-18 19:23:05
【问题描述】:
我是 asyncio 的新手,我想在我的 pyqt 应用程序中利用它来处理通过 tcp 连接进行的通信。
我做了这个简单的演示来学习如何在 asyncio 上下文中处理 QT 循环。我看过与此相关的其他帖子,但它们比我目前尝试做的要复杂得多。因此,我在一个单独的窗口中启动服务器客户端,以便它进行侦听,并尝试通过我的小部件上的简单按钮单击事件发送消息。尽可能简单......我的问题是它不起作用。
我希望能够进行单次信息交换以及端口为流打开的情况。我认为这些任务在 asyncio 中是直截了当的,但在这一点上让它与 qt 一起玩似乎很困难。
现在我得到了
RuntimeWarning: coroutine 'PushButton.sendmessage' was never awaited
rslt = self.__app.exec_()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
我不知道从哪里着手解决这个问题。
test.py
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, pyqtSlot
import sys
import asyncio
from asyncqt import QEventLoop
from async_client import tcp_echo_client
class PushButton(QWidget):
loop = None
def __init__(self,app_loop):
super(PushButton,self).__init__()
self.initUI()
self.loop = loop
def initUI(self):
self.setWindowTitle("PushButton")
self.setGeometry(400,400,300,260)
self.send_bttn = QPushButton(self)
self.send_bttn.setText("SEnd Message")
self.send_bttn.clicked.connect(self.sendmessage)
self.send_bttn.move(100,100)
@pyqtSlot()
async def sendmessage(self):
run_command = asyncio.create_task(tcp_echo_client("hey",self_loop))
asyncio.run(run_command)
if __name__ == '__main__':
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop) # NEW must set the event loop sys.exit(app.exec_())
ex = PushButton(loop)
ex.show()
with loop:
loop.run_forever()
简单的回显客户端例程
import asyncio
async def tcp_echo_client(message, loop):
reader, writer = await asyncio.open_connection('127.0.0.1', 8889,
loop=loop)
print('Send: %r' % message)
writer.write(message.encode())
data = await reader.read(100)
print('Received: %r' % data.decode())
print('Close the socket')
writer.close()
和响应服务器
import asyncio
async def handle_echo(reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print("Received %r from %r" % (message, addr))
print("Send: %r" % message)
writer.write(data)
await writer.drain()
print("Close the client socket")
writer.close()
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8889, loop=loop)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
【问题讨论】:
标签: python tcp pyqt5 python-asyncio coroutine