1

I have a fully functioning PyQt4 based application that I am now trying to embed an IPython console into for use as a kind of scripting environment.

I've roughly adapted the example from IPython's Github page to fit into my application's module system. However, if any PyQt import happens before the IPython imports

from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.qt.inprocess import QtInProcessKernelManager

I get the following error:

ImportError: 
Could not load requested Qt binding. Please ensure that
PyQt4 >= 4.7 or PySide >= 1.0.3 is available,
and only one is imported per session.

Currently-imported Qt library:   'pyqtv1'
PyQt4 installed:                 True
PySide >= 1.0.3 installed:       False
Tried to load:                   ['pyside', 'pyqt']

I've traced this error to IPython's qt module, but essentially forcing 'pyqtv1' to be loaded (by replacing api_opts = [QT_API] with api_opts = ['pyqtv1'] breaks QString inside the IPython window.

However, if I make it so that those imports happen first (by importing the module this code is in before anything else), that error goes away and it basically breaks QString completely with an ImportError: cannot import name QString.

I've verified that if I make a self-contained QApplication in the module that contains the IPython instance, making sure to import PyQt.QtGui after doing the IPython imports, it works ask expected. It's only when I try and mix the IPython code with any other PyQt code that things break.

Any suggestions as to how to fix the error?

I'm on Ubuntu Linux 12.04, and IPython is version 2.0.0-dev pulled on March 10th.

aruisdante
  • 8,875
  • 2
  • 30
  • 37
  • Have you tried using one of the released versions of IPython, like the 1.2 series? There have been a lot of changes in the 2.0 series, and this may be a bug on their end. – MattDMo Mar 10 '14 at 21:33
  • Yes, the 1.2 series doesn't have the built in facility for doing this 'natively'. That's why I'm on the development release. Otherwise I would use the code [here](http://stackoverflow.com/questions/11513132/embedding-ipython-qt-console-in-a-pyqt-application?rq=1), which is actually how the stuff in the 2.0 series came about in the first place :p – aruisdante Mar 10 '14 at 21:41

1 Answers1

0

PyQt offers two different APIs for strings: you can choose which one to use with code like this:

import sip
sip.setapi('QString', 2)
from PyQt4 import QtGui

Once you import PyQt4, that API is set and cannot be changed. On Python 2, it defaults to version 1 for backwards compatibility, but IPython requires API version 2. Version 2 is the default on Python 3, and PySide's API is equivalent to version 2.

If you've used the v1 API in your application, you cannot use the IPython Qt console embedded in that application, except by porting it to the v2 API. However, you can embed an IPython kernel in your application, and connect to it from a Qt console in a separate process.

Thomas K
  • 39,200
  • 7
  • 84
  • 86
  • Yes, I eventually figured it out by forcing v2 via setting the `QT_API` flag to be `pyqt` in *.bashrc* and wrapping all the calls to `from PyQt4.QtCore import QString` with `try ... except ImportError: QString = str`. This seems to make everything happy in running on Python 2.7x, although I actually switched back to the 1.12 release and using the original version of that code from that other SO question linked to in my OP. Although had to make sure to disable pylab or else it tries to gank all the matplotlib figures I use through my application. – aruisdante Mar 11 '14 at 21:09