1 # -----------------------------------------------------------------------------
2 # Copyright © 2014-2015 Colin Duquesnoy
3 # Copyright © 2009- The Spyder Development Team
5 # Licensed under the terms of the MIT License
6 # (see LICENSE.txt for details)
7 # -----------------------------------------------------------------------------
9 """Provides widget classes and functions."""
10 from functools
import partialmethod
12 from . import PYQT5
, PYQT6
, PYSIDE2
, PYSIDE6
13 from . import QT_VERSION
as _qt_version
17 getattr_missing_optional_dep
,
19 static_method_kwargs_wrapper
,
22 _missing_optional_names
= {}
25 def __getattr__(name
):
26 """Custom getattr to chain and wrap errors due to missing optional deps."""
27 raise getattr_missing_optional_dep(
30 optional_names
=_missing_optional_names
,
35 from PyQt5
.QtWidgets
import *
37 from PyQt6
import QtWidgets
38 from PyQt6
.QtGui
import (
45 from PyQt6
.QtWidgets
import *
47 # Attempt to import QOpenGLWidget, but if that fails,
48 # don't raise an exception until the name is explicitly accessed.
49 # See https://github.com/spyder-ide/qtpy/pull/387/
51 from PyQt6
.QtOpenGLWidgets
import QOpenGLWidget
52 except ImportError as error
:
53 _missing_optional_names
["QOpenGLWidget"] = {
54 "name": "PyQt6.QtOpenGLWidgets",
55 "missing_package": "pyopengl",
56 "import_error": error
,
59 # Map missing/renamed methods
60 QTextEdit
.setTabStopWidth
= (
61 lambda self
, *args
, **kwargs
: self
.setTabStopDistance(*args
, **kwargs
)
63 QTextEdit
.tabStopWidth
= (
64 lambda self
, *args
, **kwargs
: self
.tabStopDistance(*args
, **kwargs
)
66 QTextEdit
.print_
= lambda self
, *args
, **kwargs
: self
.print(
70 QPlainTextEdit
.setTabStopWidth
= (
71 lambda self
, *args
, **kwargs
: self
.setTabStopDistance(*args
, **kwargs
)
73 QPlainTextEdit
.tabStopWidth
= (
74 lambda self
, *args
, **kwargs
: self
.tabStopDistance(*args
, **kwargs
)
76 QPlainTextEdit
.print_
= lambda self
, *args
, **kwargs
: self
.print(
80 QApplication
.exec_
= lambda *args
, **kwargs
: possibly_static_exec(
85 QDialog
.exec_
= lambda self
, *args
, **kwargs
: self
.exec(*args
, **kwargs
)
86 QMenu
.exec_
= lambda *args
, **kwargs
: possibly_static_exec(
91 QLineEdit
.getTextMargins
= lambda self
: (
92 self
.textMargins().left(),
93 self
.textMargins().top(),
94 self
.textMargins().right(),
95 self
.textMargins().bottom(),
98 # Add removed definition for `QFileDialog.Options` as an alias of `QFileDialog.Option`
99 # passing as default value 0 in the same way PySide6 6.5+ does.
100 # Note that for PyQt5 and PySide2 those definitions are two different classes
101 # (one is the flag definition and the other the enum definition)
102 QFileDialog
.Options
= lambda value
=0: QFileDialog
.Option(value
)
104 # Allow unscoped access for enums inside the QtWidgets module
105 from .enums_compat
import promote_enums
107 promote_enums(QtWidgets
)
110 from PySide2
.QtWidgets
import *
112 from PySide6
.QtGui
import QAction
, QActionGroup
, QShortcut
, QUndoCommand
113 from PySide6
.QtWidgets
import *
115 # Attempt to import QOpenGLWidget, but if that fails,
116 # don't raise an exception until the name is explicitly accessed.
117 # See https://github.com/spyder-ide/qtpy/pull/387/
119 from PySide6
.QtOpenGLWidgets
import QOpenGLWidget
120 except ImportError as error
:
121 _missing_optional_names
["QOpenGLWidget"] = {
122 "name": "PySide6.QtOpenGLWidgets",
123 "missing_package": "pyopengl",
124 "import_error": error
,
127 # Map missing/renamed methods
128 QTextEdit
.setTabStopWidth
= (
129 lambda self
, *args
, **kwargs
: self
.setTabStopDistance(*args
, **kwargs
)
131 QTextEdit
.tabStopWidth
= (
132 lambda self
, *args
, **kwargs
: self
.tabStopDistance(*args
, **kwargs
)
134 QPlainTextEdit
.setTabStopWidth
= (
135 lambda self
, *args
, **kwargs
: self
.setTabStopDistance(*args
, **kwargs
)
137 QPlainTextEdit
.tabStopWidth
= (
138 lambda self
, *args
, **kwargs
: self
.tabStopDistance(*args
, **kwargs
)
140 QLineEdit
.getTextMargins
= lambda self
: (
141 self
.textMargins().left(),
142 self
.textMargins().top(),
143 self
.textMargins().right(),
144 self
.textMargins().bottom(),
147 # Map DeprecationWarning methods
148 QApplication
.exec_
= lambda *args
, **kwargs
: possibly_static_exec(
153 QDialog
.exec_
= lambda self
, *args
, **kwargs
: self
.exec(*args
, **kwargs
)
154 QMenu
.exec_
= lambda *args
, **kwargs
: possibly_static_exec(
160 # Passing as default value 0 in the same way PySide6 < 6.3.2 does for the `QFileDialog.Options` definition.
161 if parse(_qt_version
) > parse("6.3"):
162 QFileDialog
.Options
= lambda value
=0: QFileDialog
.Option(value
)
165 if PYSIDE2
or PYSIDE6
:
166 # Make PySide2/6 `QFileDialog` static methods accept the `directory` kwarg as `dir`
167 QFileDialog
.getExistingDirectory
= static_method_kwargs_wrapper(
168 QFileDialog
.getExistingDirectory
,
172 QFileDialog
.getOpenFileName
= static_method_kwargs_wrapper(
173 QFileDialog
.getOpenFileName
,
177 QFileDialog
.getOpenFileNames
= static_method_kwargs_wrapper(
178 QFileDialog
.getOpenFileNames
,
182 QFileDialog
.getSaveFileName
= static_method_kwargs_wrapper(
183 QFileDialog
.getSaveFileName
,
188 # Make PyQt5/6 `QFileDialog` static methods accept the `dir` kwarg as `directory`
189 QFileDialog
.getExistingDirectory
= static_method_kwargs_wrapper(
190 QFileDialog
.getExistingDirectory
,
194 QFileDialog
.getOpenFileName
= static_method_kwargs_wrapper(
195 QFileDialog
.getOpenFileName
,
199 QFileDialog
.getOpenFileNames
= static_method_kwargs_wrapper(
200 QFileDialog
.getOpenFileNames
,
204 QFileDialog
.getSaveFileName
= static_method_kwargs_wrapper(
205 QFileDialog
.getSaveFileName
,
210 # Make `addAction` compatible with Qt6 >= 6.3
211 if PYQT5
or PYSIDE2
or parse(_qt_version
) < parse("6.3"):
212 QMenu
.addAction
= partialmethod(add_action
, old_add_action
=QMenu
.addAction
)
213 QToolBar
.addAction
= partialmethod(
215 old_add_action
=QToolBar
.addAction
,