【问题标题】:How to use callbacks and futures with asyncio and the PyQt5 event loop?如何在 asyncio 和 PyQt5 事件循环中使用回调和期货?
【发布时间】:2021-07-18 20:37:21
【问题描述】:

这是我编写的一个小型测试程序,试图了解如何将 PyQt 事件循环与 asyncio 一起使用:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
from PyQt5 import QtCore
import qasync
import asyncio

async def main():
    app = QApplication(sys.argv)
    asyncio.set_event_loop(qasync.QEventLoop(app))
    window = QMainWindow()
    window.setGeometry(100, 100, 200, 200)
    button = QPushButton(window)
    button.move(50, 50)
    button.resize(100, 100)
    button.setText('Run')
    future = None
    def run_action():
        future.set_result('run clicked')
    button.clicked.connect(run_action)
    window.setWindowTitle('Testing async event loop')
    window.show()
    await asyncio.sleep(1)
    i = 0
    while True:
        future = asyncio.get_event_loop().create_future()
        result = await future
        i += 1
        if i == 4:
            break
    print("Done")

asyncio.run(main())

这给了我以下错误:

Traceback (most recent call last):
  File "/home/hakon/test/python/async/./t.py", line 36, in <module>
    asyncio.run(main())
  File "/home/hakon/.pyenv/versions/3.9.4/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/home/hakon/.pyenv/versions/3.9.4/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/home/hakon/test/python/async/./t.py", line 25, in main
    await asyncio.sleep(1)
  File "/home/hakon/.pyenv/versions/3.9.4/lib/python3.9/asyncio/tasks.py", line 654, in sleep
    return await future
RuntimeError: Task <Task pending name='Task-1' coro=<main() running at /home/hakon/test/python/async/./t.py:25> cb=[_run_until_complete_cb() at /home/hakon/.pyenv/versions/3.9.4/lib/python3.9/asyncio/base_events.py:184]> got Future <Future pending> attached to a different loop

知道我在这里缺少什么吗?如何改进此代码?

【问题讨论】:

  • 我不确定,但您可能需要在asyncio.run(main()) 之前使用asyncio.set_event_loop

标签: python pyqt5 python-asyncio


【解决方案1】:

问题是您正在运行一个事件循环,然后您刚刚创建了 Qt 事件循环。有两种可能的解决方案:

  • 在执行协程main之前设置eventloop:

    import asyncio
    import sys
    
    from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
    import qasync
    
    
    async def main():
        window = QMainWindow()
        window.setGeometry(100, 100, 200, 200)
        button = QPushButton(window)
        button.move(50, 50)
        button.resize(100, 100)
        button.setText("Run")
        future = None
    
        def run_action():
            if future is not None:
                future.set_result("run clicked")
    
        button.clicked.connect(run_action)
        window.setWindowTitle("Testing async event loop")
        window.show()
        await asyncio.sleep(1)
        i = 0
        while True:
            future = asyncio.get_event_loop().create_future()
            result = await future
            i += 1
            if i == 4:
                break
        print("Done")
    
    
    app = QApplication(sys.argv)
    loop = qasync.QEventLoop(app)
    asyncio.set_event_loop(loop)
    with loop:
        loop.run_until_complete(main())
    
  • 或者使用 qasync.run():

    import asyncio
    import sys
    
    from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
    import qasync
    
    
    async def main():
        window = QMainWindow()
        window.setGeometry(100, 100, 200, 200)
        button = QPushButton(window)
        button.move(50, 50)
        button.resize(100, 100)
        button.setText("Run")
        future = None
    
        def run_action():
            if future is not None:
                future.set_result("run clicked")
    
        button.clicked.connect(run_action)
        window.setWindowTitle("Testing async event loop")
        window.show()
        await asyncio.sleep(1)
        i = 0
        while True:
            future = asyncio.get_event_loop().create_future()
            result = await future
            i += 1
            if i == 4:
                break
        print("Done")
    
    
    qasync.run(main())
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多