Permalink
Browse files

update qt import priority per recent discussion

QT_API now supersedes matplotlib rcParam, so the v2 API will always be
used if QT_API=pyqt (as long as matplotlib isn't too old)

Default behavior for no QT_API is unchanged
  • Loading branch information...
minrk committed Jul 6, 2011
1 parent 6bc24fa commit c808c841d69039d77b9a58586071d9baf6163833
Showing with 71 additions and 62 deletions.
  1. +58 −49 IPython/external/qt_for_kernel.py
  2. +13 −13 docs/source/interactive/reference.txt
@@ -2,74 +2,83 @@
This is the import used for the `gui=qt` or `pylab=qt` initialization.
-Priority:
+Import Priority:
-if matplotlib has been imported:
- # get here with pylab=qt
- if matplotlib doesn't support v2 (<= 1.0.1):
- use PyQt4 @v1
- else:
- ask matplotlib which Qt it's using
- if it said PyQt:
- use PyQt4 @v1
- elif it said PySide:
- use PySide
+if matplotlib has been imported and doesn't support v2 (<= 1.0.1):
+ use PyQt4 @v1
-if matplotlib had nothing to say, or matplotlib not imported:
- # get here with gui=qt, or if matplotlib didn't tell us anything
- ask ETS' QT_API env variable
+Next, ask ETS' QT_API env variable
+
+if QT_API not set:
+ ask matplotlib via rcParams['backend.qt4']
+ if it said PyQt:
+ use PyQt4 @v1
+ elif it said PySide:
+ use PySide
- if QT_API not set:
- # this is the *default* path - no information was given
+ else: (matplotlib said nothing)
+ # this is the default path - nobody told us anything
try:
PyQt @v1
except:
fallback on PySide
- else:
- use PyQt @v2 or PySide, depending on QT_API
- because ETS doesn't work with v1.
+else:
+ use PyQt @v2 or PySide, depending on QT_API
+ because ETS doesn't work with PyQt @v1.
+
"""
import os
import sys
matplotlib = sys.modules.get('matplotlib')
-if matplotlib:
- # ask matplotlib first (get here with pylab=qt)
- if matplotlib.__version__ <= '1.0.1':
- # 1.0.1 doesn't support pyside or v2, so force PyQt @v1
- mod = 'PyQt4'
- else:
- # this rc option has been proposed, but is yet not in matplotlib master
- # as of writing.
- mod = matplotlib.rcParams.get('backend.qt4', None)
+if matplotlib and matplotlib.__version__ <= '1.0.1':
+ # 1.0.1 doesn't support pyside or v2, so stick with PyQt @v1,
+ # and ignore everything else
+ from PyQt4 import QtCore, QtGui
else:
- # get here with `gui=qt`
- mod = None
-
-if mod is None:
- # matplotlib not imported or had nothing to say.
- # ask QT_API ETS variable
+ # ask QT_API ETS variable *first*
QT_API = os.environ.get('QT_API', None)
if QT_API is None:
- try:
- # default to unconfigured PyQt4
- from PyQt4 import QtCore, QtGui
- except ImportError:
- # fallback on PySide
+ # QT_API not set, ask matplotlib if it was imported (e.g. `pylab=qt`)
+ if matplotlib:
+ # this rc option has been proposed, but is not yet in matplotlib master
+ # as of writing.
+ mpqt = matplotlib.rcParams.get('backend.qt4', None)
+ else:
+ mpqt = None
+ if mpqt is None:
+ # matplotlib not imported or had nothing to say.
try:
- from PySide import QtCore, QtGui
+ # default to unconfigured PyQt4
+ from PyQt4 import QtCore, QtGui
except ImportError:
- raise ImportError('Cannot import PySide or PyQt4')
+ # fallback on PySide
+ try:
+ from PySide import QtCore, QtGui
+ except ImportError:
+ raise ImportError('Cannot import PySide or PyQt4')
+ elif mpqt.lower() == 'pyqt4':
+ # import PyQt4 unconfigured
+ from PyQt4 import QtCore, QtGui
+ elif mpqt.lower() == 'pyside':
+ from PySide import QtCore, QtGui
+ else:
+ raise ImportError("unhandled value for backend.qt4 from matplotlib: %r"%mpqt)
else:
# QT_API specified, use PySide or PyQt+v2 API from external.qt
# this means ETS is likely to be used, which requires v2
- from IPython.external.qt import QtCore, QtGui
+ try:
+ from IPython.external.qt import QtCore, QtGui
+ except ValueError as e:
+ if 'API' in str(e):
+ # API mismatch, give more meaningful message
+ raise ImportError("""
+ Assinging the ETS variable `QT_API=pyqt` implies PyQt's v2 API for
+ QString and QVariant, but PyQt has already been imported
+ with v1 APIs. You must unset QT_API to work with PyQt4
+ in its default mode.
+""")
+ else:
+ raise
-elif mod.lower() == 'pyqt4':
- # import PyQt4 unconfigured
- from PyQt4 import QtCore, QtGui
-elif mod.lower() == 'pyside':
- from PySide import QtCore, QtGui
-else:
- raise ImportError("unhandled value for backend.qt4 from matplotlib: %r"%mod)
@@ -1269,29 +1269,29 @@ v2 is also the default for PyQt4 on Python 3. IPython's code for the QtConsole
uses v2, but you can still use any interface in your code, since the
Qt frontend is in a different process.
-If you launch IPython in pylab mode with ``ipython pylab=qt``, then IPython
-will ask matplotlib which Qt library to use, via the 'backend.qt4' rcParam.
-If matplotlib is version 1.0.1 or older, then IPython will always use PyQt4
-without setting the v2 APIs.
-
-If you just integrate the Qt event loop with ``ipython gui=qt``, then IPython
-has a few more possibilities. The default will be to import PyQt4 without
-configuration of the APIs, thus matching what most applications would expect.
-It will fall back of PySide if PyQt4 is unavailable.
+The default will be to import PyQt4 without configuration of the APIs, thus
+matching what most applications would expect. It will fall back of PySide if
+PyQt4 is unavailable.
If specified, IPython will respect the environment variable ``QT_API`` used
by ETS. ETS 4.0 also works with both PyQt4 and PySide, but it requires
-PyQt4 to use the v2 API. So if ``QT_API=pyside`` PySide will be used,
-and if ``QT_API=pyqt`` then PyQt4 will be used with the v2 API for
+PyQt4 to use its v2 API. So if ``QT_API=pyside`` PySide will be used,
+and if ``QT_API=pyqt`` then PyQt4 will be used *with the v2 API* for
QString and QVariant, so ETS codes like MayaVi will also work with IPython.
+If you launch IPython in pylab mode with ``ipython pylab=qt``, then IPython
+will ask matplotlib which Qt library to use (only if QT_API is *not set*),
+via the 'backend.qt4' rcParam.
+If matplotlib is version 1.0.1 or older, then IPython will always use PyQt4
+without setting the v2 APIs, since neither v2 PyQt nor PySide work.
+
.. warning::
- Note that this means for ETS to work with PyQt4, ``QT_API`` *must* be set to
+ Note that this means for ETS 4 to work with PyQt4, ``QT_API`` *must* be set to
work with IPython's qt integration, because otherwise PyQt4 will be loaded in
an incompatible mode.
- It also means that you must not have ``QT_API`` set if you want to
+ It also means that you must *not* have ``QT_API`` set if you want to
use ``gui=qt`` with code that requires PyQt4 API v1.

0 comments on commit c808c84

Please sign in to comment.