The*_*ice 2 python tcp coroutine pyqt5 python-asyncio
我是 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
Run Code Online (Sandbox Code Playgroud)
我不知道从哪里开始解决这个问题。
测试.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()
Run Code Online (Sandbox Code Playgroud)
简单的 echo 客户端例程
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()
Run Code Online (Sandbox Code Playgroud)
和响应服务器
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()
Run Code Online (Sandbox Code Playgroud)
问题是,如果你调用一个协程槽,那么你必须使用asyncSlot装饰器,也不要使用ayncion.run()but await(除了消除其他拼写错误)。
import sys
import asyncio
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from asyncqt import QEventLoop, asyncSlot
from async_client import tcp_echo_client
class PushButton(QWidget):
loop = None
def __init__(self, loop=None):
super(PushButton, self).__init__()
self.initUI()
self.loop = loop or asyncio.get_event_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)
@asyncSlot()
async def sendmessage(self):
await tcp_echo_client("hey", self.loop)
if __name__ == "__main__":
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
ex = PushButton(loop)
ex.show()
with loop:
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3964 次 |
| 最近记录: |