PyQt5 使用 aiohttp 发送异步请求
本文使用PyQt5
演示,如何结合aiohttp
库,发送异步请求
代码结构
本文中全部代码全在test_async_request.py
这一个文件中编码,步骤中有变动的地方会注释标注,无改动的不会重复显示出来,需要看完整代码的,可直接移步到末尾。
需要安装PyQt5,aiohttp==3.8.6,asyncqt
一. 创建测试页面
首先我们需要创建一个窗口,用于显示请求响应的内容
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_async_request.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 使用 aiohttp 发送异步请求
"""
import sys
import asyncio
from PyQt5.QtWidgets import QApplication, QPushButton, QLabel, QVBoxLayout, QWidget
import aiohttp
from asyncqt import QEventLoopclass MainWindow(QWidget):def __init__(self):super().__init__()self.setFixedSize(800, 80)self.setWindowTitle("PyQt5 使用 aiohttp")# 创建 QLabel QPushButtonself.label = QLabel("按下按钮发出请求", self)self.button = QPushButton("发送 GET 请求", self)# 设置布局layout = QVBoxLayout()layout.addWidget(self.label)layout.addWidget(self.button)self.setLayout(layout)if __name__ == "__main__":app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec_())
运行后,可以得到下面这样的窗口
二. 实现异步请求
使用aiohttp
实现异步请求
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_async_request.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 使用 aiohttp 发送异步请求
"""
class MainWindow(QWidget):def __init__(self):super().__init__()... # 忽略self.button.clicked.connect(self.handle_request)def handle_request(self):# 在事件循环中运行异步函数asyncio.create_task(self.fetch_data())async def fetch_data(self):url = 'https://api.github.com/repos/YQBaobao/RollerCoaster/tags'async with aiohttp.ClientSession() as session:async with session.get(url) as response:if response.status == 200:data = await response.json()tags = [tag['name'] for tag in data][:3]# 更新标签self.label.setText(f"Title: {tags}")else:self.label.setText(f"请求失败: {response.status}")
但是此时我们不能直接运行,因为:PyQt5
的事件循环与 asyncio
的事件循环不兼容,需要手动运行 asyncio
的事件循环。
三. 手动启动事件循环
为了解决事件循环不兼容问题,可以使用 asyncio
的 QEventLoop
或者 asyncqt
库来桥接 asyncio
和 PyQt5
的事件循环。
以下是使用 asyncqt
库举例
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File : test_async_request.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 使用 aiohttp 发送异步请求
"""
class MainWindow(QWidget):... # 忽略无变化if __name__ == "__main__":app = QApplication(sys.argv)# 创建 asyncio 事件循环loop = QEventLoop(app)asyncio.set_event_loop(loop)window = MainWindow()window.show()# sys.exit(app.exec_())# 在 asyncio 事件循环中运行应用程序with loop:loop.run_forever()
启动,并点击发送 GET 请求
按钮:
四. 完整代码
完整代码见:GitHub,Gitee
本文章的原文地址
GitHub主页