[英]asyncio create task and aiohttp , 'no running event loop'
Im trying to make a Pyqt5 app with aiohttp request, and asyncio tasks.我正在尝试使用 aiohttp 请求和 asyncio 任务制作一个 Pyqt5 应用程序。 Im using quamash package too and it requires Python 3.7 so i installed this version.(it didn't work on Python 3.10) The main reason i use asyncio and quamash is because i want to do requests and without freezing the GUI of the app.
我也在使用 quamash package,它需要 Python 3.7,所以我安装了这个版本。(它在 Python 3.10 上不起作用)我使用 asyncio 和 quamash 的主要原因是因为我想做请求而不冻结应用程序的 GUI。
I get this error when i click the Start button and close the app:单击“开始”按钮并关闭应用程序时出现此错误:
Task exception was never retrieved
future: <Task finished coro=<App.rotator() done, defined at C:\Users\Zsolt\Documents\python-example\stack_exmaple.py:37> exception=RuntimeError('no running event loop')>
Traceback (most recent call last):
File "C:\Users\Zsolt\Documents\python-example\stack_exmaple.py", line 41, in rotator
response = await get()
File "C:\Users\Zsolt\Documents\python-example\stack_exmaple.py", line 51, in get
async with session.get(pokemon_url) as resp:
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\client.py", line 1138, in __aenter__
self._resp = await self._coro
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\client.py", line 533, in _request
async with ceil_timeout(real_timeout.connect):
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\helpers.py", line 734, in ceil_timeout
return async_timeout.timeout(None)
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\async_timeout\__init__.py", line 30, in timeout
loop = _get_running_loop()
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\async_timeout\__init__.py", line 236, in _get_running_loop
return asyncio.get_running_loop()
RuntimeError: no running event loop
Here is the full code:这是完整的代码:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QKeySequence, QPalette, QColor
from PyQt5.QtCore import Qt
from PyQt5 import QtGui, QtCore
import asyncio
import aiohttp
import quamash
import os.path
import json
import sys
class App(QWidget):
run = 0
response = ''
def __init__(self, loop):
super().__init__()
btn = QPushButton('Start', self)
btn.resize(btn.sizeHint())
btn.clicked.connect(self.start)
self.setGeometry(200, 200, 700, 400)
self.display = QLabel(self)
self.display.resize(200, 500)
self.display.move(1, 50)
self.count = 0
self.show()
self.loop = loop
self.tasks = []
self.tasks.append(loop.create_task(self.rotator()))
async def rotator(self):
while await asyncio.sleep(0, True):
if (self.run == 1):
self.count += 1
response = await get()
self.display.setText(str(response))
def start (self):
self.run = 1
async def get():
async with aiohttp.ClientSession() as session:
pokemon_url = 'https://pokeapi.co/api/v2/pokemon/151'
async with session.get(pokemon_url) as resp:
pokemon = await resp.json()
print(pokemon)
return pokemon
app = QApplication(sys.argv)
app.setApplicationName("Sample ;)")
loop = quamash.QEventLoop(app)
asyncio.set_event_loop(loop)
with loop:
window = App(loop)
window.show()
loop.run_forever()
If i comment out the response = await get()
it works, it counts the self.count += 1 and it shows the variable on self.display.setText(str(self.count))
.如果我注释掉
response = await get()
它起作用,它会计算 self.count += 1 并在self.display.setText(str(self.count))
上显示变量。 But i need to get it to work with the aiohttp request so it should print out the response from the request.但我需要让它与 aiohttp 请求一起工作,所以它应该打印出请求的响应。
TLDR; TLDR; replace quamash with qasync
用 qasync 替换quamash
In asyncio, a task always exists when async code is executed.在 asyncio 中,执行异步代码时始终存在任务。 Like in a multithreaded program at least the main thread is present.
就像在多线程程序中一样,至少存在主线程。 If quamash doesn't follow the rule -- it is not aiohttp problem.
如果 quamash 不遵守规则——这不是 aiohttp 问题。
quamash is not maintained anymore, the latest release was made 3.5 years ago. quamash 不再维护,最新版本是 3.5 年前发布的。 The maintained successor is qasync which has no this bug and works with the latest aiohttp perfectly fine.
维护的继任者是 qasync,它没有这个错误,并且可以完美地与最新的 aiohttp 配合使用。
FWIW, you may also use the qtinter package to replace quamash, which supports Python 3.7 to 3.11. FWIW,您也可以使用qtinter package 替换 quamash,它支持 Python 3.7 到 3.11。 ( Disclaimer : I'm the author of
qtinter
.) (免责声明:我是
qtinter
的作者。)
With qtinter
the last few lines need to be changed to the following:使用
qtinter
,最后几行需要更改为以下内容:
app = QApplication(sys.argv)
app.setApplicationName("Sample ;)")
with qtinter.using_asyncio_from_qt():
window = App(asyncio.get_running_loop())
window.show()
app.exec()
I fixed the error by installing previous release of aiohttp Orignally i had aiohttp 3.8.1.dist installed and i knew it was working for me before on other version of aiohttp, so i looked up pypi.org/project/aiohttp/#history and turn out i had to uninstall aiohttp and install aiohttp==3.7.4.我通过安装以前版本的 aiohttp 修复了错误 最初我安装了 aiohttp 3.8.1.dist 并且我知道它之前在其他版本的 aiohttp 上对我有用,所以我查找了pypi.org/project/aiohttp/#history和原来我必须卸载 aiohttp 并安装 aiohttp==3.7.4。
Commands:命令:
pip uninstall aiohttp
pip install aiohttp==3.7.4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.