我在使用此处RichJupyterWidget
提供的小部件实现的 PyQt5 应用程序中有一个嵌入式 Jupyter 控制台。
控制台集成本身工作正常,Jupyter 控制台嵌入在一个小部件中,可以执行 Python 代码,结果显示在控制台本身内。
然而,我需要做的是,每当我运行一些返回 Pandas 的代码时,都会 在控制台外部DataFrame
显示它。TableView
这是我的实现的一个工作示例:
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from qtconsole.inprocess import QtInProcessKernelManager
from qtconsole.rich_jupyter_widget import RichJupyterWidget
class IPythonConsole:
def __init__(self):
self._kernel_manager = None
self._kernel = None
self._kernel_client = None
self.start()
@property
def kernel_manager(self) -> QtInProcessKernelManager:
return self._kernel_manager
@property
def kernel(self):
return self._kernel
@property
def kernel_client(self):
return self._kernel_client
def start(self):
self._kernel_manager = QtInProcessKernelManager()
self._kernel_manager.start_kernel()
self._kernel = self._kernel_manager.kernel
self._kernel.gui = 'qt'
self._kernel_client = self._kernel_manager.client()
self._kernel_client.start_channels()
def stop(self):
self._kernel_client.stop_channels()
self._kernel_manager.shutdown_kernel()
class IPythonWidget(RichJupyterWidget):
"""RichIPythonWidget implementation to integrate the IPython console inside a Qt Widget"""
def __init__(self):
super().__init__()
self._console = IPythonConsole()
self.kernel_manager = self._console.kernel_manager
self.kernel_client = self._console.kernel_client
@property
def console(self):
return self._console
def run_command(self, command_str):
self.execute(command_str, False, True)
def close(self):
self._console.stop()
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = QMainWindow()
ipython_widget = IPythonWidget()
main_window.layout().addWidget(ipython_widget)
main_window.setFixedHeight(768)
main_window.setFixedWidth(1024)
ipython_widget.run_command("import pandas as pd\n"
"df = pd.DataFrame({'Test': ['a', 'b', 'c']})\n"
"df")
main_window.show()
sys.exit(app.exec_())
到目前为止,我试图覆盖以下方法RichJupyterWidget
:
def _handle_execute_result(self, msg):
"""Overridden to handle rich data types, like SVG."""
self.log.debug("execute_result: %s", msg.get('content', ''))
if self.include_output(msg):
self.flush_clearoutput()
content = msg['content']
prompt_number = content.get('execution_count', 0)
data = content['data']
metadata = msg['content']['metadata']
if 'image/svg+xml' in data:
self._pre_image_append(msg, prompt_number)
self._append_svg(data['image/svg+xml'], True)
self._append_html(self.output_sep2, True)
elif 'image/png' in data:
[...]
但不幸的是,当返回 a 时DataFrame
, msg 包含一个带有DataFrame
HTML 格式内容的字符串。
编辑
我能够DataFrame
从内核外壳中获取对象,如下所示:
if self.ipython_widget.execute("df = pd.DataFrame({'Test': ['a', 'b', 'c']})\n", False, False):
df = self.ipython_widget.console.kernel.shell.user_ns.get('df')
不幸的是,这只会在我自己运行代码时起作用,而不是当用户在控制台中输入内容时,而且我必须知道包含数据框的变量的名称。