簡體   English   中英

python 與 AsyncKernelManager 異步,Qt 未執行

[英]python async with AsyncKernelManager and Qt not executing

我正在嘗試在 Qt 應用程序中的 jupyter kernel 中執行代碼。 我有下面的代碼片段應該異步運行代碼然后打印結果

import sys
import asyncio

import qasync
from qasync import QApplication
from PySide6.QtWidgets import QWidget
from jupyter_client import AsyncKernelManager


CODE = """print('test')"""


class Test():
    def __init__(self):
        kernel_manager = AsyncKernelManager()
        kernel_manager.start_kernel()

        self.client = kernel_manager.client()
        self.client.start_channels()

    def run(self):
        loop = asyncio.get_event_loop()
        asyncio.ensure_future(self.execute(), loop=loop)

    async def execute(self):
        self.client.execute(CODE)
        response: Coroutine = self.client.get_shell_msg()
        print('Before')
        res = await response
        print('After')


def main():
    app = QApplication(sys.argv)
    test = Test()
    test.run()
    sys.exit(app.exec())


main()

通過以上我得到以下 output

/tmp/test/test.py:16: RuntimeWarning: coroutine 'KernelManager._async_start_kernel' was never awaited
  kernel_manager.start_kernel()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/tmp/test/test.py:22: DeprecationWarning: There is no current event loop
  loop = asyncio.get_event_loop()

因此嘗試根據qasync中的示例將代碼調整為類似

async def main():
    app = QApplication(sys.argv)
    test = Test()
    test.run()
    sys.exit(app.exec())


qasync.run(main())

將導致以下異常

Traceback (most recent call last):
  File "/tmp/test/test.py", line 40, in <module>
    qasync.run(main())
  File "/tmp/test/.venv/lib/python3.10/site-packages/qasync/__init__.py", line 821, in run
    return asyncio.run(*args, **kwargs)
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/tmp/test/.venv/lib/python3.10/site-packages/qasync/__init__.py", line 409, in run_until_complete
    return future.result()
  File "/tmp/test/test.py", line 34, in main
    app = QApplication(sys.argv)
RuntimeError: Please destroy the QApplication singleton before creating a new QApplication instance.

在這一點上我很迷茫,有人知道如何讓它工作嗎?

你必須創建一個 QEventLoop,同時 start_kernel 必須使用 await。 另一方面,它首先導入 PySide6,然后導入依賴於 PySide6 的其他庫(如 qasync),以便它可以推斷出正確的 Qt 綁定。

import sys
import asyncio
from functools import cached_property

from PySide6.QtWidgets import QApplication
import qasync

from jupyter_client import AsyncKernelManager


CODE = """print('test')"""


class Test:
    @cached_property
    def kernel_manager(self):
        return AsyncKernelManager()

    @cached_property
    def client(self):
        return self.kernel_manager.client()

    async def start(self):
        await self.kernel_manager.start_kernel()
        self.client.start_channels()
        asyncio.ensure_future(self.execute())

    async def execute(self):
        self.client.execute(CODE)
        response = self.client.get_shell_msg()
        print("Before")
        res = await response
        print("After", res)


def main():
    app = QApplication(sys.argv)
    loop = qasync.QEventLoop(app)
    asyncio.set_event_loop(loop)
    test = Test()
    asyncio.ensure_future(test.start())
    with loop:
        loop.run_forever()


if __name__ == "__main__":
    main()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM