I am trying to embed an IPython qtconsole in my application, in a similar way that I can embed an IPython text console, thus:
from IPython.frontend.terminal.embed import InteractiveShellEmbed
myobj={'jason':10}
shell = InteractiveShellEmbed()
shell.user_ns = myobj
shell()
I can start a QT console in my application by using
from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp
app = IPythonQtConsoleApp()
app.initialize()
app.start()
But this has no access to existing objects.
I can start a kernel in my application which has access to existing objects, using:
import IPython
myobj={'jason':10}
IPython.embed_kernel(local_ns=myobj)
#No more code executes
And then connect to it using
ipython qtconsole --existing
Or, in another python script:
from IPython.lib.kernel import find_connection_file
from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp
cf=find_connection_file("*")
app = IPythonQtConsoleApp(existing=cf[-1])
app.initialize()
app.start()
But these are not monolithic solutions, both require another shell. The kernel runs in a thread that does not yield, so no more code executes until the kernel exists.
So, my question is, how can I achieve the above in one script?
I've tried using threads and multiprocessing, but as embed_kernel() never returns and obviously must be run before IPythonQTConsoleApp() or the connection file would be missing, I don't see how to manage this.
P.S. Will somebody with a rep of >1000 please add a qtconsole tag.
To embed a kernel without blocking, have a look at this example from the IPython repository. IPython knows some clever tricks for integrating itself with the Qt event loop, so you can run a console and your application at the same time. For things like interactive debugging, this is the way to go.
If you need to embed the console into your own application, we've just merged an in-process kernel. Have a look at this example. You'd need to use IPython development versions until the next release, but it would be great to get some early testing.