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, |
|
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 |
|
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 |
|
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