qt_for_kernel.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """ Import Qt in a manner suitable for an IPython kernel.
  2. This is the import used for the `gui=qt` or `matplotlib=qt` initialization.
  3. Import Priority:
  4. if Qt has been imported anywhere else:
  5. use that
  6. if matplotlib has been imported and doesn't support v2 (<= 1.0.1):
  7. use PyQt4 @v1
  8. Next, ask QT_API env variable
  9. if QT_API not set:
  10. ask matplotlib what it's using. If Qt4Agg or Qt5Agg, then use the
  11. version matplotlib is configured with
  12. else: (matplotlib said nothing)
  13. # this is the default path - nobody told us anything
  14. try in this order:
  15. PyQt default version, PySide, PyQt5
  16. else:
  17. use what QT_API says
  18. """
  19. # NOTE: This is no longer an external, third-party module, and should be
  20. # considered part of IPython. For compatibility however, it is being kept in
  21. # IPython/external.
  22. import os
  23. import sys
  24. from IPython.utils.version import check_version
  25. from IPython.external.qt_loaders import (load_qt, loaded_api, QT_API_PYSIDE,
  26. QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT5,
  27. QT_API_PYQTv1, QT_API_PYQT_DEFAULT)
  28. _qt_apis = (QT_API_PYSIDE, QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT5, QT_API_PYQTv1,
  29. QT_API_PYQT_DEFAULT)
  30. #Constraints placed on an imported matplotlib
  31. def matplotlib_options(mpl):
  32. if mpl is None:
  33. return
  34. backend = mpl.rcParams.get('backend', None)
  35. if backend == 'Qt4Agg':
  36. mpqt = mpl.rcParams.get('backend.qt4', None)
  37. if mpqt is None:
  38. return None
  39. if mpqt.lower() == 'pyside':
  40. return [QT_API_PYSIDE]
  41. elif mpqt.lower() == 'pyqt4':
  42. return [QT_API_PYQT_DEFAULT]
  43. elif mpqt.lower() == 'pyqt4v2':
  44. return [QT_API_PYQT]
  45. raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" %
  46. mpqt)
  47. elif backend == 'Qt5Agg':
  48. mpqt = mpl.rcParams.get('backend.qt5', None)
  49. if mpqt is None:
  50. return None
  51. if mpqt.lower() == 'pyqt5':
  52. return [QT_API_PYQT5]
  53. raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" %
  54. mpqt)
  55. def get_options():
  56. """Return a list of acceptable QT APIs, in decreasing order of
  57. preference
  58. """
  59. #already imported Qt somewhere. Use that
  60. loaded = loaded_api()
  61. if loaded is not None:
  62. return [loaded]
  63. mpl = sys.modules.get('matplotlib', None)
  64. if mpl is not None and not check_version(mpl.__version__, '1.0.2'):
  65. #1.0.1 only supports PyQt4 v1
  66. return [QT_API_PYQT_DEFAULT]
  67. qt_api = os.environ.get('QT_API', None)
  68. if qt_api is None:
  69. #no ETS variable. Ask mpl, then use default fallback path
  70. return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE,
  71. QT_API_PYQT5, QT_API_PYSIDE2]
  72. elif qt_api not in _qt_apis:
  73. raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
  74. (qt_api, ', '.join(_qt_apis)))
  75. else:
  76. return [qt_api]
  77. api_opts = get_options()
  78. QtCore, QtGui, QtSvg, QT_API = load_qt(api_opts)