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