I want to be able to bring up an interactive python terminal from my python application. Some, but not all, variables in my program needs to be exposed to the interpreter.>
First draft of updated version of my code to support IPython 0.13
'''
Created on 18-03-2012
@author: Paweł Jarosz
'''
import os, sys
import atexit
from PySide import QtCore, QtGui
from IPython.zmq.ipkernel import IPKernelApp
from IPython.lib.kernel import find_connection_file, connect_qtconsole
from IPython.frontend.qt.kernelmanager import QtKernelManager
from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.config.application import catch_config_error
class IPythonLocalKernelApp(IPKernelApp):
"""IPython kernel application with nonblocking loop, running in dedicated thread.
example:
app = QtGui.QApplication([])
kernelapp = IPythonLocalKernelApp.instance()
kernelapp.start()
namespace = kernelapp.get_user_namespace()
namespace["QtGui"]=QtGui
namespace["QtCore"]=QtCore
app.exec_()"""
#DEFAULT_INSTANCE_ARGS starting commandline
DEFAULT_INSTANCE_ARGS = ['qtconsole','--pylab=inline', '--colors=linux']
@catch_config_error
def initialize(self, argv=None):
super(IPythonLocalKernelApp, self).initialize(argv)
self.kernel.eventloop = self.loop_qt4_nonblocking
def loop_qt4_nonblocking(self, kernel):
"""Non-blocking version of the ipython qt4 kernel loop"""
kernel.timer = QtCore.QTimer()
kernel.timer.timeout.connect(kernel.do_one_iteration)
kernel.timer.start(1000*kernel._poll_interval)
def start(self, argv=DEFAULT_INSTANCE_ARGS):
"""Starts IPython kernel app
argv: arguments passed to kernel
"""
self.initialize(argv)
#self.heartbeat.start()
#if self.poller is not None:
# self.poller.start()
self.kernel.start()
super(IPythonLocalKernelApp, self).start()
def get_connection_file(self):
"""Returne current kernel connection file."""
return self.connection_file
def get_user_namespace(self):
"""Returns current kernel userspace dict"""
return self.kernel.shell.user_ns
class IPythonConsoleQtWidget(RichIPythonWidget):
"""Ipython console Qt4+ widget
Usage example:
app = QtGui.QApplication([])
kernelapp = IPythonLocalKernelApp.instance()
kernelapp.start()
namespace = kernelapp.get_user_namespace()
widget = IPythonConsoleQtWidget()
widget.set_default_style(colors='linux')
widget.connect_kernel(connection_file=kernelapp.get_connection_file())
# if you won't to connect to remote kernel:
widget.connect_kernel(connection_file='kernel-16098.json')
widget.show()
namespace["widget"] = widget
namespace["QtGui"]=QtGui
namespace["QtCore"]=QtCore
app.exec_()"""
_connection_file = None
def __init__(self, *args, **kw):
RichIPythonWidget.__init__(self, *args, **kw)
self._existing = True
self._may_close = False
self._confirm_exit = False
def _init_kernel_manager(self):
km = QtKernelManager(connection_file=self._connection_file, config=self.config)
km.load_connection_file()
km.start_channels(hb=self._heartbeat)
self.kernel_manager = km
atexit.register(self.kernel_manager.cleanup_connection_file)
def connect_kernel(self, connection_file, heartbeat=False):
"""Connect's to ipython kernel.
connection_file - connection file to use
heartbeat - should start heartbeat server? Workaround for problems with inproc embedded kernels
(right click save image as/save as html kills kernel heartbeat/pool(??) serwer """
self._heartbeat = heartbeat
if os.path.exists(connection_file):
self._connection_file = connection_file
else:
self._connection_file = find_connection_file(connection_file)
self._init_kernel_manager()
app = QtGui.QApplication([])
kernelapp = IPythonLocalKernelApp.instance()
kernelapp.start()
namespace = kernelapp.get_user_namespace()
widget = IPythonConsoleQtWidget()
widget.set_default_style(colors='linux')
widget.connect_kernel(connection_file=kernelapp.get_connection_file())
# if you won't to connect to remote kernel:
# widget.connect_kernel(connection_file='kernel-16098.json')
widget.show()
namespace["widget"] = widget
namespace["QtGui"]=QtGui
namespace["QtCore"]=QtCore
app.exec_()