##// END OF EJS Templates
Copy across PySide2 support from Qtconsole
Thomas Kluyver -
Show More
@@ -33,10 +33,10 b' import sys'
33 33
34 34 from IPython.utils.version import check_version
35 35 from IPython.external.qt_loaders import (load_qt, loaded_api, QT_API_PYSIDE,
36 QT_API_PYQT, QT_API_PYQT5,
36 QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT5,
37 37 QT_API_PYQTv1, QT_API_PYQT_DEFAULT)
38 38
39 _qt_apis = (QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQT5, QT_API_PYQTv1,
39 _qt_apis = (QT_API_PYSIDE, QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT5, QT_API_PYQTv1,
40 40 QT_API_PYQT_DEFAULT)
41 41
42 42 #Constraints placed on an imported matplotlib
@@ -83,7 +83,8 b' def get_options():'
83 83 qt_api = os.environ.get('QT_API', None)
84 84 if qt_api is None:
85 85 #no ETS variable. Ask mpl, then use default fallback path
86 return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE, QT_API_PYQT5]
86 return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE,
87 QT_API_PYQT5, QT_API_PYSIDE2]
87 88 elif qt_api not in _qt_apis:
88 89 raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
89 90 (qt_api, ', '.join(_qt_apis)))
@@ -64,14 +64,21 b' def commit_api(api):'
64 64 """Commit to a particular API, and trigger ImportErrors on subsequent
65 65 dangerous imports"""
66 66
67 if api == QT_API_PYSIDE2:
68 ID.forbid('PySide')
69 ID.forbid('PyQt4')
70 ID.forbid('PyQt5')
67 71 if api == QT_API_PYSIDE:
72 ID.forbid('PySide2')
68 73 ID.forbid('PyQt4')
69 74 ID.forbid('PyQt5')
70 75 elif api == QT_API_PYQT5:
76 ID.forbid('PySide2')
71 77 ID.forbid('PySide')
72 78 ID.forbid('PyQt4')
73 79 else: # There are three other possibilities, all representing PyQt4
74 80 ID.forbid('PyQt5')
81 ID.forbid('PySide2')
75 82 ID.forbid('PySide')
76 83
77 84
@@ -83,7 +90,7 b' def loaded_api():'
83 90
84 91 Returns
85 92 -------
86 None, 'pyside', 'pyqt', 'pyqt5', or 'pyqtv1'
93 None, 'pyside2', 'pyside', 'pyqt', 'pyqt5', or 'pyqtv1'
87 94 """
88 95 if 'PyQt4.QtCore' in sys.modules:
89 96 if qtapi_version() == 2:
@@ -92,19 +99,21 b' def loaded_api():'
92 99 return QT_API_PYQTv1
93 100 elif 'PySide.QtCore' in sys.modules:
94 101 return QT_API_PYSIDE
102 elif 'PySide2.QtCore' in sys.modules:
103 return QT_API_PYSIDE2
95 104 elif 'PyQt5.QtCore' in sys.modules:
96 105 return QT_API_PYQT5
97 106 return None
98 107
99 108
100 109 def has_binding(api):
101 """Safely check for PyQt4/5 or PySide, without importing submodules
110 """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
102 111
103 112 Supports Python <= 3.3
104 113
105 114 Parameters
106 115 ----------
107 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyqtdefault']
116 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
108 117 Which module to check for
109 118
110 119 Returns
@@ -124,7 +133,7 b' def has_binding(api):'
124 133 imp.find_module('QtCore', mod.__path__)
125 134 imp.find_module('QtGui', mod.__path__)
126 135 imp.find_module('QtSvg', mod.__path__)
127 if api == QT_API_PYQT5:
136 if api in (QT_API_PYQT5, QT_API_PYSIDE2):
128 137 # QT5 requires QtWidgets too
129 138 imp.find_module('QtWidgets', mod.__path__)
130 139
@@ -137,13 +146,13 b' def has_binding(api):'
137 146 return False
138 147
139 148 def has_binding_new(api):
140 """Safely check for PyQt4/5 or PySide, without importing submodules
149 """Safely check for PyQt4/5, PySide or PySide2, without importing submodules
141 150
142 151 Supports Python >= 3.4
143 152
144 153 Parameters
145 154 ----------
146 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyqtdefault']
155 api : str [ 'pyqtv1' | 'pyqt' | 'pyqt5' | 'pyside' | 'pyside2' | 'pyqtdefault']
147 156 Which module to check for
148 157
149 158 Returns
@@ -277,6 +286,22 b' def import_pyside():'
277 286 from PySide import QtGui, QtCore, QtSvg
278 287 return QtCore, QtGui, QtSvg, QT_API_PYSIDE
279 288
289 def import_pyside2():
290 """
291 Import PySide2
292
293 ImportErrors raised within this function are non-recoverable
294 """
295 from PySide2 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport
296
297 # Join QtGui and QtWidgets for Qt4 compatibility.
298 QtGuiCompat = types.ModuleType('QtGuiCompat')
299 QtGuiCompat.__dict__.update(QtGui.__dict__)
300 QtGuiCompat.__dict__.update(QtWidgets.__dict__)
301 QtGuiCompat.__dict__.update(QtPrintSupport.__dict__)
302
303 return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2
304
280 305
281 306 def load_qt(api_options):
282 307 """
@@ -288,7 +313,7 b' def load_qt(api_options):'
288 313 Parameters
289 314 ----------
290 315 api_options: List of strings
291 The order of APIs to try. Valid items are 'pyside',
316 The order of APIs to try. Valid items are 'pyside', 'pyside2',
292 317 'pyqt', 'pyqt5', 'pyqtv1' and 'pyqtdefault'
293 318
294 319 Returns
@@ -304,12 +329,14 b' def load_qt(api_options):'
304 329 bindings (either becaues they aren't installed, or because
305 330 an incompatible library has already been installed)
306 331 """
307 loaders = {QT_API_PYSIDE: import_pyside,
332 loaders = {
333 QT_API_PYSIDE2: import_pyside2,
334 QT_API_PYSIDE: import_pyside,
308 335 QT_API_PYQT: import_pyqt4,
309 336 QT_API_PYQT5: import_pyqt5,
310 337 QT_API_PYQTv1: partial(import_pyqt4, version=1),
311 338 QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None)
312 }
339 }
313 340
314 341 for api in api_options:
315 342
@@ -329,16 +356,18 b' def load_qt(api_options):'
329 356 else:
330 357 raise ImportError("""
331 358 Could not load requested Qt binding. Please ensure that
332 PyQt4 >= 4.7, PyQt5 or PySide >= 1.0.3 is available,
359 PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available,
333 360 and only one is imported per session.
334 361
335 362 Currently-imported Qt library: %r
336 363 PyQt4 available (requires QtCore, QtGui, QtSvg): %s
337 364 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
338 365 PySide >= 1.0.3 installed: %s
366 PySide2 installed: %s
339 367 Tried to load: %r
340 368 """ % (loaded_api(),
341 369 has_binding(QT_API_PYQT),
342 370 has_binding(QT_API_PYQT5),
343 371 has_binding(QT_API_PYSIDE),
372 has_binding(QT_API_PYSIDE2),
344 373 api_options))
General Comments 0
You need to be logged in to leave comments. Login now