【问题标题】:Embedding Ipython into a PyQt4 App将 Ipython 嵌入到 PyQt4 应用程序中
【发布时间】:2013-05-24 14:26:12
【问题描述】:

我将 Python 嵌入到 PyQt4 应用程序中,当时它处于 beta 阶段,并且只在 Ipython 的 git 分支上工作。我已经有一年左右没有看代码了,从那以后发生了很多变化——在 Ipython 中似乎有很多重构。我目前安装了 13.2

所以,我需要嵌入 Python,并且我需要它存在于我的 PyQt4 应用程序中,以便我可以使用来自我的 Python 应用程序的数据更改内核的 user_ns。用于从 git 处理 python 版本的代码如下:

import sys
sys.path.insert(0, "../../ipython") #pickup ipython from git in a nonstd dir

from IPython.embedded.ipkernel import EmbeddedKernel
from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.frontend.qt.embedded_kernelmanager import QtEmbeddedKernelManager
from IPython.lib import guisupport
from PyQt4.QtGui import QFrame,QHBoxLayout
from PyQt4.QtGui import QApplication
from collections import namedtuple



class IpythonEmbeddedWidget(QFrame):
    def __init__(self):
        QFrame.__init__(self)
        self._layout = QHBoxLayout()
        self._kernel = EmbeddedKernel()
        self._kernel_manager = QtEmbeddedKernelManager(kernel = self._kernel)
        self._kernel_manager.start_channels()
        self._kernel.frontends.append(self._kernel_manager)
        self._shell_widget = RichIPythonWidget()
        app = guisupport.get_app_qt4()
        self._shell_widget.exit_requested.connect(app.quit)
        self._shell_widget.kernel_manager = self._kernel_manager
        self._layout.addWidget(self._shell_widget)
        self.setLayout(self._layout)
        self._kernel.shell.run_cell("import nltk")
        self._kernel.shell.run_cell("import sys")
        self._kernel.shell.run_cell("sys.path.append('../ipython_scripts')")
        self._kernel.shell.run_cell("cd ../ipython_scripts")


    def set_shell_focus(self):
        pass

if __name__ == '__main__':
    app = QApplication(sys.argv)
    iew = IpythonEmbeddedWidget()
    iew.show()
    app.exec_()
    sys.exit()

那么,我需要进行哪些更改才能使其与当前 (13.2) 版本的 Ipython 一起工作?

编辑:

13.2 没有进程内内核功能。您仍然需要开发分支。驱使我问这个问题的不是我更新了我的开发分支,而是更新我机器上的 QT/PyQt4 使现有代码中断。我随后更新了 Ipython 开发版本,该版本要求我在 API 发生变化时重构我的代码。

【问题讨论】:

    标签: python qt pyqt4 ipython


    【解决方案1】:

    我走了同样的路,但最终使用了 IPython 开发,因为嵌入解决方案更干净,没有讨厌的 input() / help() 错误。

    这是 0.13.x 的解决方法:https://stackoverflow.com/a/12375397/532513 -- 问题是,例如,如果您使用 help(),一切都会冻结。

    在开发 IPython 中,一切都简单得多。这是一个工作示例:

    from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
    from IPython.frontend.qt.inprocess import QtInProcessKernelManager
    from IPython.lib import guisupport
    from PyQt4.QtGui import QApplication
    
    app = QApplication(sys.argv)
    
    kernel_manager = QtInProcessKernelManager()
    kernel_manager.start_kernel()
    kernel = kernel_manager.kernel
    kernel.gui = 'qt4'
    
    kernel_client = kernel_manager.client()
    kernel_client.start_channels()
    
    def stop():
        kernel_client.stop_channels()
        kernel_manager.shutdown_kernel()
        # here you should exit your application with a suitable call
        sys.exit()
    
    widget = RichIPythonWidget()
    widget.kernel_manager = kernel_manager
    widget.kernel_client = kernel_client
    widget.exit_requested.connect(stop)
    widget.setWindowTitle("IPython shell")
    
    ipython_widget = widget
    ipython_widget.show()
    
    app.exec_()
    sys.exit()
    

    【讨论】:

    • 这是正确的做法,因为 0.13.2 没有进程内模块。
    • 这个code 运行。但是在运行代码时,我从 ipython 的 git 版本中获得了 errors 版本。有什么线索吗?我在 OS X 上并使用 QT (4.8.4) 和 PyQt4 (4.10.1)。
    • 我看到了问题。您正在加载 PyQt4 API 版本 1(Python 2 上的默认值)。在没有 QT_API 环境变量的情况下,IPython 加载代码会尝试 PySide,然后是 PyQt4 API 版本 2。在您的情况下,它会找到 PyQt4 2,但这与您已经加载的 1 不匹配。要修复,请将您的 PyQt4 导入代码更改为以下内容: import sip; sip.setapi('QString', 2);从 PyQt4.QtGui 导入 QApplication
    • 这适用于 1.1.0,但我认为最好链接到新的 example in the github tree。我在相关问题here中做了稍微详细一点的回答
    【解决方案2】:

    这是我制作并一直在使用 PyQt4 和 PySide 应用程序QIPythonWidget 的东西。我没有在 IPython 上做任何工作,我只是对它进行了破解,所以可能有更好的方法来做这件事,但这很有效,并且没有遇到问题。希望对您有所帮助。

    【讨论】:

    • 我发现这对于 IPython 0.13.1 来说是一种非常有用的方法,但不幸的是它不适用于较新的版本。 official example 适用于 IPython 1.1.0+。
    猜你喜欢
    • 1970-01-01
    • 2013-02-16
    • 2012-07-15
    • 1970-01-01
    • 2010-09-23
    • 2011-11-22
    • 2013-05-29
    • 2018-12-21
    • 1970-01-01
    相关资源
    最近更新 更多