Python 尝试在使用pyqt构建的主窗口中导入Jubyter控制台

Python 尝试在使用pyqt构建的主窗口中导入Jubyter控制台,python,pyqt5,ipython,jupyter,Python,Pyqt5,Ipython,Jupyter,我遇到了一个问题,我在pyqt5构建的主窗口中导入了一个Jubyter控制台,当主窗口运行时,控制台空白是空的。当我将控制台作为单个小部件运行时,它正在工作 控制台作为单个小部件映像运行: 控制台代码: import os from typing import Tuple, Dict, Callable from qtpy.QtCore import QObject, Signal, QThread, QWaitCondition, QMutex from qtpy.QtGui import

我遇到了一个问题,我在pyqt5构建的主窗口中导入了一个Jubyter控制台,当主窗口运行时,控制台空白是空的。当我将控制台作为单个小部件运行时,它正在工作

控制台作为单个小部件映像运行:

控制台代码:

import os
from typing import Tuple, Dict, Callable

from qtpy.QtCore import QObject, Signal, QThread, QWaitCondition, QMutex
from qtpy.QtGui import QTextCursor
from qtpy.QtWidgets import QMessageBox, QMenu
from qtconsole.manager import QtKernelManager
from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole import styles
from qtconsole.styles import default_light_syntax_style, default_light_style_sheet

default_dark_style_template = styles.default_template + """\
    .in-prompt { color: #ff00ff; }
    .out-prompt { color: #ff0000; }
"""
default_dark_style_sheet = default_dark_style_template % dict(
    bgcolor='#19232d', fgcolor='white', select="#ccc")
default_dark_syntax_style = 'default'

class ConsoleInitThread(QObject):
    initialized = Signal(object, object)

    def __init__(self, *args, **kwargs):
        super(ConsoleInitThread, self).__init__(*args, **kwargs)
        self.mutex = QMutex()
        self.wait_condition = QWaitCondition()

    def run(self):
        self.mutex.lock()
        kernel_manager = QtKernelManager(kernel_name='python3')
        kernel_manager.start_kernel()

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

        # notify to update ui
        self.initialized.emit(kernel_manager, kernel_client)

        # wait for exit
        self.wait_condition.wait(self.mutex)
        self.mutex.unlock()

        # stop channels and kernel
        kernel_client.stop_channels()
        kernel_manager.shutdown_kernel(now=True)  # add now=True; Fix exit error;  200924 liugang

    def stop(self):
        self.wait_condition.wakeAll()


class MlGIpythonConsole(RichJupyterWidget):

    def __init__(self, *args, **kwargs):
        super(MlGIpythonConsole, self).__init__(*args, **kwargs)
        self.is_first_execution = True
        self.confirm_restart = False

        self.commands_pool = []
        self.command_callback_pool: Dict[str, Callable] = {}

    def change_ui_theme(self, style: str):
        """
        改变界面主题颜色
        :param style:
        :return:
        """
        if style == 'Fusion':
            self.style_sheet = default_light_style_sheet
            self.syntax_style = default_light_syntax_style

        elif style == 'Qdarkstyle':
            self.style_sheet = default_dark_style_sheet
            self.syntax_style = default_dark_syntax_style

        elif style.lower() == 'windowsvista':
            self.style_sheet = default_light_style_sheet
            self.syntax_style = default_light_syntax_style

        elif style.lower() == 'windows':
            self.style_sheet = default_light_style_sheet
            self.syntax_style = default_light_syntax_style

    def _handle_kernel_died(self, since_last_heartbit):
        self.is_first_execution = True
        self.restart_kernel(None, True)
        self.initialize_ipython_builtins()
        self.execute_command('')
        return True

    def _handle_execute_input(self, msg):
        super()._handle_execute_result(msg)

    def setup_ui(self):
        self.kernel_manager = None
        self.kernel_client = None
        # initialize by thread
        self.init_thread = QThread(self)
        self.console_object = ConsoleInitThread()
        self.console_object.moveToThread(self.init_thread)
        self.console_object.initialized.connect(self.slot_initialized)
        self.init_thread.finished.connect(self.console_object.deleteLater)
        self.init_thread.finished.connect(self.init_thread.deleteLater)
        self.init_thread.started.connect(self.console_object.run)
        self.init_thread.start()
        cursor: QTextCursor = self._prompt_cursor
        cursor.movePosition(QTextCursor.End)

        self.context_menu = QMenu()
        restart_action = self.context_menu.addAction(self.tr('Restart'))
        restart_action.triggered.connect(self._restart_kernel)

    def _custom_context_menu_requested(self, pos):
        self.context_menu.exec_(self.mapToGlobal(pos))

    def _restart_kernel(self, arg1):
        self.is_first_execution = True
        self.restart_kernel(None, True)
        self.initialize_ipython_builtins()
        self.execute_command('')
        return True

    def slot_initialized(self, kernel_manager, kernel_client):
        """
        Args:
            kernel_manager: `qtconsole.manager.QtKernelManager`
            kernel_client: `qtconsole.manager.QtKernelManager.client`

        Returns:
        """
        self.kernel_manager = kernel_manager
        self.kernel_client = kernel_client
        self.initialize_ipython_builtins()

    def initialize_ipython_builtins(self):
        return

    def _update_list(self):
        try:
            super(MlGIpythonConsole, self)._update_list()
        except BaseException:
            import traceback
            traceback.print_exc()

    def _banner_default(self):
        """
        自定义控制台开始的文字
        Returns:
        """
        return 'Welcome To IPy Console!\n'

    def closeEvent(self, event):
        if self.init_thread.isRunning():
            self.console_object.stop()
            self.init_thread.quit()
            self.init_thread.wait(500)
        super(MlGIpythonConsole, self).closeEvent(event)

    def execute_file(self, file: str, hidden: bool = False):
        if not os.path.exists(file) or not file.endswith('.py'):
            raise FileNotFoundError(f'{file} not found or invalid')
        base = os.path.basename(file)
        cmd = os.path.splitext(base)[0]
        with open(file, 'r', encoding='utf-8') as f:
            source = f.read()

        self.execute_command(source, hidden=hidden, hint_text=cmd)

    def execute_command(self, source, hidden: bool = False,
                        hint_text: str = '') -> str:
        """

        :param source:
        :param hidden:
        :param hint_text: 运行代码前显示的提示
        :return: str 执行命令的 msgid
        """
        cursor: QTextCursor = self._prompt_cursor
        cursor.movePosition(QTextCursor.End)
        # 运行文件时,显示文件名,无换行符,执行选中内容时,包含换行符
        # 检测换行符,在ipy console中显示执行脚本内容
        hint_row_list = hint_text.split("\n")
        for hint in hint_row_list:
            if hint != "":
                cursor.insertText('%s\n' % hint)
                self._insert_continuation_prompt(cursor)
        else:
            # 删除多余的continuation_prompt
            self.undo()

        self._finalize_input_request()  # display input string buffer in console.
        cursor.movePosition(QTextCursor.End)
        if self.kernel_client is None:
            self.commands_pool.append((source, hidden, hint_text))
            return ''
        else:
            return self.pmexecute(source, hidden)

    def _handle_stream(self, msg):
        print(msg['content'].get('text'), msg)
        parent_header = msg.get('parent_header')
        print('msg_id', parent_header['msg_id'])
        if parent_header is not None:
            msg_id = parent_header.get('msg_id')  # 'fee0bee5-074c00d093b1455be6d166b1_10'']
            if msg_id in self.command_callback_pool.keys():
                callback = self.command_callback_pool.pop(msg_id)
                assert callable(callback)
                callback()
        cursor: QTextCursor = self._prompt_cursor
        cursor.movePosition(QTextCursor.End)
        super()._handle_stream(msg)

    def append_stream(self, text):
        """重写的方法。原本before_prompt属性是False。"""
        self._append_plain_text(text, before_prompt=False)

    def pmexecute(self, source: str, hidden: bool = False) -> str:
        """
        执行代码并且返回Msgid
        :param source:
        :param hidden:
        :return:
        """
        is_legal, msg = self.is_source_code_legal(source)
        if not is_legal:
            QMessageBox.warning(self, '警告', msg)
            source = ''
        msg_id = self.kernel_client.execute(source, hidden)
        self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user')
        self._hidden = hidden
        if not hidden:
            self.executing.emit(source)
        return msg_id
        # super()._execute(source, hidden)

    def is_source_code_legal(self, source_code: str) -> Tuple[bool, str]:
        """
        判断注入到shell的命令是否合法,不合法的话,就避免执行这个函数。
        :param source_code:
        :return:
        """
        return True, ''


if __name__ == '__main__':
    import sys
    from qtpy.QtWidgets import QApplication

    app = QApplication(sys.argv)
    w = MlGIpythonConsole()
    w.show()
    w.setup_ui()
    sys.exit(app.exec_())

主窗口代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'call.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets
from widgets import MlGIpythonConsole


class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(840, 598)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 840, 22))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menubar)

        self.hLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.hLayout.setObjectName("hLayout")

        self.console = MlGIpythonConsole()
        self.hLayout.addWidget(self.console)

        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.actionNew = QtWidgets.QAction(MainWindow)
        self.actionNew.setObjectName("actionNew")
        self.menu.addAction(self.actionNew)
        self.menubar.addAction(self.menu.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.menu.setTitle(_translate("MainWindow", "函数调用"))
        self.actionNew.setText(_translate("MainWindow", "New..."))

```
和运行代码:

导入系统 从PyQt5.QtWidgets导入QApplication,QMainWindow 进口电话 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app=QApplication(sys.argv) MainWindow=QMainWindow() c=call.Ui\u主窗口() c、 setupUi(主窗口) MainWindow.show() sys.exit(app.exec_())
我错过了什么?

输入错误:在
self.hLayout.addWidget(self.console)之后添加
self.console.setup\u ui()