Python 尝试在使用pyqt构建的主窗口中导入Jubyter控制台
我遇到了一个问题,我在pyqt5构建的主窗口中导入了一个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
控制台代码:
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()