Как заставить qtconsole работать под Qthread? - PullRequest
0 голосов
/ 08 февраля 2019

Ниже приведен минимальный рабочий пример проблемы.Он работает нормально, но, если я запускаю какую-то тяжелую задачу на оболочке jupyter, он зависает в графическом интерфейсе, пока работа не будет выполнена.

Вы можете столкнуться с этим на полосе прокрутки, которая будет зависать, если вы выполните что-то вроде:

In [1]: n = 50000000
   ...: while n > 0:
   ...:     n -=1
   ...:     x = n**4

К сожалению, это происходит также с основным фреймом GUI (в который встроена qtconsole).

Вопрос в том, как установить отдельный Qthread, который будет выполнять qtconsole на фоне моего основного графического интерфейса pyqt5?

Я вижу, что в IDE "Spyder" есть именно то, что мне нужно (т.е. инструмент со встроенной оболочкой Ipython, который запускает задания в фоновом режиме), но я не могу понять из их проекта, как они туда попали.

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_())  
...