简体   繁体   中英

Embedding Ipython into a PyQt4 App

I got Python embedded into a PyQt4 app back when it was in the beta stages and only worked on a git branch of Ipython. I haven't looked at the code for a year or so, and a LOT has changed since then -- lots of refactoring it seems in Ipython. I currently have 13.2 installed

So, I need to embed Python, and I need it to exist within my PyQt4 app, so that I may alter the user_ns of the kernel with data from my Python App. The code that used to work against the python version from git is as follows :

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

So, What do I need to change to go to get it to work with the current (13.2) version of Ipython ?

edit:

13.2 does not have the inprocess-kernel functionality. You still need the development branch. What drove me to ask this question was not that I updated my development branch, but that updating QT/PyQt4 on my machine got the existing code to break. I subsequently updated the Ipython development version which required me to refactor my code as the API had changed.

I went down the same path, but ended up using IPython dev as the embedding solution is cleaner and has no nasty input() / help() bugs.

Here is a work-around for 0.13.x: https://stackoverflow.com/a/12375397/532513 -- problem is, if you use help() for example, everything freezes.

In the development IPython, it's all much simpler. Here's a working example:

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

Here's something that I've made and have been using with both PyQt4 and PySide apps QIPythonWidget . I don't do any work on IPython, I just hacked away at it so there is probably a better way of doing it but this works and haven't ran into problems with it. Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM