|
8 | 8 |
|
9 | 9 | """Provides QtGui classes and functions.""" |
10 | 10 |
|
11 | | -from . import PYQT6, PYQT5, PYSIDE2, PYSIDE6 |
| 11 | +from . import PYQT6, PYQT5, PYSIDE2, PYSIDE6, QtModuleNotInstalledError |
| 12 | +from .utils import getattr_missing_optional_dep |
| 13 | + |
| 14 | + |
| 15 | +_missing_optional_names = {} |
| 16 | + |
| 17 | +_QTOPENGL_NAMES = { |
| 18 | + 'QOpenGLBuffer', |
| 19 | + 'QOpenGLContext', |
| 20 | + 'QOpenGLContextGroup', |
| 21 | + 'QOpenGLDebugLogger', |
| 22 | + 'QOpenGLDebugMessage', |
| 23 | + 'QOpenGLFramebufferObject', |
| 24 | + 'QOpenGLFramebufferObjectFormat', |
| 25 | + 'QOpenGLPixelTransferOptions', |
| 26 | + 'QOpenGLShader', |
| 27 | + 'QOpenGLShaderProgram', |
| 28 | + 'QOpenGLTexture', |
| 29 | + 'QOpenGLTextureBlitter', |
| 30 | + 'QOpenGLVersionProfile', |
| 31 | + 'QOpenGLVertexArrayObject', |
| 32 | + 'QOpenGLWindow', |
| 33 | +} |
| 34 | + |
| 35 | +def __getattr__(name): |
| 36 | + """Custom getattr to chain and wrap errors due to missing optional deps.""" |
| 37 | + raise getattr_missing_optional_dep( |
| 38 | + name, module_name=__name__, optional_names=_missing_optional_names) |
| 39 | + |
12 | 40 |
|
13 | 41 | if PYQT5: |
14 | 42 | from PyQt5.QtGui import * |
|
18 | 46 | elif PYQT6: |
19 | 47 | from PyQt6 import QtGui |
20 | 48 | from PyQt6.QtGui import * |
21 | | - from PyQt6.QtOpenGL import * |
| 49 | + |
| 50 | + # Attempt to import QOpenGL* classes, but if that fails, |
| 51 | + # don't raise an exception until the name is explicitly accessed. |
| 52 | + # See https://github.com/spyder-ide/qtpy/pull/387/ |
| 53 | + try: |
| 54 | + from PyQt6.QtOpenGL import * |
| 55 | + except ImportError as error: |
| 56 | + for name in _QTOPENGL_NAMES: |
| 57 | + _missing_optional_names[name] = { |
| 58 | + 'name': 'PyQt6.QtOpenGL', |
| 59 | + 'missing_package': 'pyopengl', |
| 60 | + 'import_error': error, |
| 61 | + } |
| 62 | + |
22 | 63 | QFontMetrics.width = lambda self, *args, **kwargs: self.horizontalAdvance(*args, **kwargs) |
23 | 64 | QFontMetricsF.width = lambda self, *args, **kwargs: self.horizontalAdvance(*args, **kwargs) |
24 | 65 |
|
|
42 | 83 | QFontMetrics.width = lambda self, *args, **kwargs: self.horizontalAdvance(*args, **kwargs) |
43 | 84 | elif PYSIDE6: |
44 | 85 | from PySide6.QtGui import * |
45 | | - from PySide6.QtOpenGL import * |
| 86 | + |
| 87 | + # Attempt to import QOpenGL* classes, but if that fails, |
| 88 | + # don't raise an exception until the name is explicitly accessed. |
| 89 | + # See https://github.com/spyder-ide/qtpy/pull/387/ |
| 90 | + try: |
| 91 | + from PySide6.QtOpenGL import * |
| 92 | + except ImportError as error: |
| 93 | + for name in _QTOPENGL_NAMES: |
| 94 | + _missing_optional_names[name] = { |
| 95 | + 'name': 'PySide6.QtOpenGL', |
| 96 | + 'missing_package': 'pyopengl', |
| 97 | + 'import_error': error, |
| 98 | + } |
46 | 99 |
|
47 | 100 | # Backport `QFileSystemModel` moved to QtGui in Qt6 |
48 | 101 | from PySide6.QtWidgets import QFileSystemModel |
@@ -121,3 +174,4 @@ def movePositionPatched( |
121 | 174 | QSinglePointEvent.globalPos = lambda self: self.globalPosition().toPoint() |
122 | 175 | QSinglePointEvent.globalX = lambda self: self.globalPosition().toPoint().x() |
123 | 176 | QSinglePointEvent.globalY = lambda self: self.globalPosition().toPoint().y() |
| 177 | + |
0 commit comments