jupyter / qtconsole

Jupyter Qt Console
https://qtconsole.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
417 stars 200 forks source link

No current event loop when running in qthread #534

Open svartkanin opened 2 years ago

svartkanin commented 2 years ago

I'm trying to use qtconsole inside a QThread

import sys

from PySide6.QtCore import QThread
from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole.inprocess import QtInProcessKernelManager
from PySide6.QtWidgets import QApplication

class Runner(RichJupyterWidget, QThread):
    def __init__(self):
        super().__init__()

        kernel_manager = QtInProcessKernelManager(kernel_name='python3')
        kernel_manager.start_kernel()

        kernel_client = kernel_manager.client()
        kernel_client.start_channels()

        self.kernel = kernel_manager.kernel

        self.kernel_manager = kernel_manager
        self.kernel_client = kernel_client

    def run(self):
        self.execute("""a = 1/0""")
        ret = self.kernel.shell.user_ns
        print(ret)

app = QApplication(sys.argv)
test = Runner()
test.start()

sys.exit(app.exec())

But I'm receiving the below error

Traceback (most recent call last):
  File "/tmp/test/test.py", line 67, in run
    self.execute("""a = 1/0""")
  File "/tmp/test/.venv/lib/python3.10/site-packages/qtconsole/console_widget.py", line 660, in execute
    self.do_execute(source, True, '')
  File "/tmp/test/.venv/lib/python3.10/site-packages/qtconsole/history_console_widget.py", line 42, in do_execute
    super().do_execute(source, complete, indent)
  File "/tmp/test/.venv/lib/python3.10/site-packages/qtconsole/console_widget.py", line 670, in do_execute
    self._execute(source, False)
  File "/tmp/test/.venv/lib/python3.10/site-packages/qtconsole/frontend_widget.py", line 285, in _execute
    msg_id = self.kernel_client.execute(source, hidden)
  File "/tmp/test/.venv/lib/python3.10/site-packages/ipykernel/inprocess/client.py", line 114, in execute
    self._dispatch_to_kernel(msg)
  File "/tmp/test/.venv/lib/python3.10/site-packages/ipykernel/inprocess/client.py", line 182, in _dispatch_to_kernel
    loop = asyncio.get_event_loop()
  File "/usr/lib/python3.10/asyncio/events.py", line 656, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Dummy-2'.

Is this generally not possible or do I have to do some magic to get this to work?

ccordoba12 commented 2 years ago

I don't think this is possible because qtconsole starts an external process (i.e. the kernel) to run code on it (the error you got is related to that).

Perhaps this works with the InProcess kernel (i.e. a kernel that runs in the same process) but I don't know if that's what you want.

svartkanin commented 2 years ago

@ccordoba12 thanks for the reply, I'll see what I can come up with