问题
A minimum working example of the problem is below. It works fine but, if I run some heavy task on the jupyter shell, it hangs the GUI until the job is done.
You may experienced this on the scrollbar which will hang if you execute something like:
In [1]: n = 50000000
...: while n > 0:
...: n -=1
...: x = n**4
Unfortunately this is happening also to the master GUI frame (on which the qtconsole is embedded to).
The question is, how to set a separate Qthread that execute the qtconsole in the background of my main pyqt5 GUI?
I see that the "Spyder" IDE has exactly what I want, (i.e. tool with embedded Ipython shell, which runs jobs in the background), but I cant understand from their project how they get there.
import sys
from PyQt5 import QtWidgets, QtCore
from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole.inprocess import QtInProcessKernelManager
from qtconsole.console_widget import ConsoleWidget
class ConsoleWidget_embed(RichJupyterWidget,ConsoleWidget):
global fit
def __init__(self, customBanner=None, *args, **kwargs):
super(ConsoleWidget_embed, self).__init__(*args, **kwargs)
if customBanner is not None:
self.banner = customBanner
self.kernel_manager = QtInProcessKernelManager()
self.kernel_manager.start_kernel(show_banner=True)
self.kernel_manager.kernel.gui = 'qt'
self.kernel = self.kernel_manager.kernel
self.kernel_client = self._kernel_manager.client()
self.kernel_client.start_channels()
def stop():
self.kernel_client.stop_channels()
self.kernel_manager.shutdown_kernel()
self.guisupport.get_app_qt().exit()
self.exit_requested.connect(stop)
def push_vars(self, variableDict):
"""
Given a dictionary containing name / value pairs, push those variables
to the Jupyter console widget
"""
self.kernel_manager.kernel.shell.push(variableDict)
def clear(self):
"""
Clears the terminal
"""
self._control.clear()
def print_text(self, text):
"""
Prints some plain text to the console
"""
self._append_plain_text(text, before_prompt=True)
def execute_command(self, command):
"""
Execute a command in the frame of the console widget
"""
self._execute(command, False)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main = ConsoleWidget_embed()
main.show()
sys.exit(app.exec_())
来源:https://stackoverflow.com/questions/54583405/how-to-make-qtconsole-to-work-under-qthread