File: QtWidgets.py

package info (click to toggle)
git-cola 4.13.0-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 6,480 kB
  • sloc: python: 36,938; sh: 304; makefile: 223; xml: 100; tcl: 62
file content (252 lines) | stat: -rw-r--r-- 7,990 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# -----------------------------------------------------------------------------
# Copyright © 2014-2015 Colin Duquesnoy
# Copyright © 2009- The Spyder Development Team
#
# Licensed under the terms of the MIT License
# (see LICENSE.txt for details)
# -----------------------------------------------------------------------------

"""Provides widget classes and functions."""
from functools import partialmethod

from . import PYQT5, PYQT6, PYSIDE2, PYSIDE6
from . import QT_VERSION as _qt_version
from . import parse
from ._utils import (
    add_action,
    getattr_missing_optional_dep,
    possibly_static_exec,
    static_method_kwargs_wrapper,
)

_missing_optional_names = {}


def __getattr__(name):
    """Custom getattr to chain and wrap errors due to missing optional deps."""
    raise getattr_missing_optional_dep(
        name,
        module_name=__name__,
        optional_names=_missing_optional_names,
    )


if PYQT5:
    from PyQt5.QtWidgets import *
elif PYQT6:
    from PyQt6 import QtWidgets
    from PyQt6.QtGui import (
        QActionGroup,
        QFileSystemModel,
        QShortcut,
        QUndoCommand,
    )
    from PyQt6.QtWidgets import *

    from qtpy.QtGui import QAction  # See spyder-ide/qtpy#461

    # Attempt to import QOpenGLWidget, but if that fails,
    # don't raise an exception until the name is explicitly accessed.
    # See https://github.com/spyder-ide/qtpy/pull/387/
    try:
        from PyQt6.QtOpenGLWidgets import QOpenGLWidget
    except ImportError as error:
        _missing_optional_names["QOpenGLWidget"] = {
            "name": "PyQt6.QtOpenGLWidgets",
            "missing_package": "pyopengl",
            "import_error": error,
        }

    # Map missing/renamed methods
    QTextEdit.setTabStopWidth = (
        lambda self, *args, **kwargs: self.setTabStopDistance(*args, **kwargs)
    )
    QTextEdit.tabStopWidth = (
        lambda self, *args, **kwargs: self.tabStopDistance(*args, **kwargs)
    )
    QTextEdit.print_ = lambda self, *args, **kwargs: self.print(
        *args,
        **kwargs,
    )
    QPlainTextEdit.setTabStopWidth = (
        lambda self, *args, **kwargs: self.setTabStopDistance(*args, **kwargs)
    )
    QPlainTextEdit.tabStopWidth = (
        lambda self, *args, **kwargs: self.tabStopDistance(*args, **kwargs)
    )
    QPlainTextEdit.print_ = lambda self, *args, **kwargs: self.print(
        *args,
        **kwargs,
    )
    QApplication.exec_ = lambda *args, **kwargs: possibly_static_exec(
        QApplication,
        *args,
        **kwargs,
    )
    QDialog.exec_ = lambda self, *args, **kwargs: self.exec(*args, **kwargs)
    QMenu.exec_ = lambda *args, **kwargs: possibly_static_exec(
        QMenu,
        *args,
        **kwargs,
    )
    QLineEdit.getTextMargins = lambda self: (
        self.textMargins().left(),
        self.textMargins().top(),
        self.textMargins().right(),
        self.textMargins().bottom(),
    )

    # Add removed definition for `QFileDialog.Options` as an alias of `QFileDialog.Option`
    # passing as default value 0 in the same way PySide6 6.5+ does.
    # Note that for PyQt5 and PySide2 those definitions are two different classes
    # (one is the flag definition and the other the enum definition)
    QFileDialog.Options = lambda value=0: QFileDialog.Option(value)

    # Allow unscoped access for enums inside the QtWidgets module
    from .enums_compat import promote_enums

    promote_enums(QtWidgets)
    del QtWidgets
elif PYSIDE2:
    from PySide2.QtWidgets import *
elif PYSIDE6:
    from PySide6.QtGui import QActionGroup, QShortcut, QUndoCommand
    from PySide6.QtWidgets import *

    from qtpy.QtGui import QAction  # See spyder-ide/qtpy#461

    # Attempt to import QOpenGLWidget, but if that fails,
    # don't raise an exception until the name is explicitly accessed.
    # See https://github.com/spyder-ide/qtpy/pull/387/
    try:
        from PySide6.QtOpenGLWidgets import QOpenGLWidget
    except ImportError as error:
        _missing_optional_names["QOpenGLWidget"] = {
            "name": "PySide6.QtOpenGLWidgets",
            "missing_package": "pyopengl",
            "import_error": error,
        }

    # Map missing/renamed methods
    QTextEdit.setTabStopWidth = (
        lambda self, *args, **kwargs: self.setTabStopDistance(*args, **kwargs)
    )
    QTextEdit.tabStopWidth = (
        lambda self, *args, **kwargs: self.tabStopDistance(*args, **kwargs)
    )
    QPlainTextEdit.setTabStopWidth = (
        lambda self, *args, **kwargs: self.setTabStopDistance(*args, **kwargs)
    )
    QPlainTextEdit.tabStopWidth = (
        lambda self, *args, **kwargs: self.tabStopDistance(*args, **kwargs)
    )
    QLineEdit.getTextMargins = lambda self: (
        self.textMargins().left(),
        self.textMargins().top(),
        self.textMargins().right(),
        self.textMargins().bottom(),
    )

    # Map DeprecationWarning methods
    QApplication.exec_ = lambda *args, **kwargs: possibly_static_exec(
        QApplication,
        *args,
        **kwargs,
    )
    QDialog.exec_ = lambda self, *args, **kwargs: self.exec(*args, **kwargs)
    QMenu.exec_ = lambda *args, **kwargs: possibly_static_exec(
        QMenu,
        *args,
        **kwargs,
    )

    # Passing as default value 0 in the same way PySide6 < 6.3.2 does for the `QFileDialog.Options` definition.
    if parse(_qt_version) > parse("6.3"):
        QFileDialog.Options = lambda value=0: QFileDialog.Option(value)


if PYSIDE2 or PYSIDE6:
    # Make PySide2/6 `QFileDialog` static methods accept the `directory` kwarg as `dir`
    QFileDialog.getExistingDirectory = static_method_kwargs_wrapper(
        QFileDialog.getExistingDirectory,
        "directory",
        "dir",
    )
    QFileDialog.getOpenFileName = static_method_kwargs_wrapper(
        QFileDialog.getOpenFileName,
        "directory",
        "dir",
    )
    QFileDialog.getOpenFileNames = static_method_kwargs_wrapper(
        QFileDialog.getOpenFileNames,
        "directory",
        "dir",
    )
    QFileDialog.getSaveFileName = static_method_kwargs_wrapper(
        QFileDialog.getSaveFileName,
        "directory",
        "dir",
    )
else:
    # Make PyQt5/6 `QFileDialog` static methods accept the `dir` kwarg as `directory`
    QFileDialog.getExistingDirectory = static_method_kwargs_wrapper(
        QFileDialog.getExistingDirectory,
        "dir",
        "directory",
    )
    QFileDialog.getOpenFileName = static_method_kwargs_wrapper(
        QFileDialog.getOpenFileName,
        "dir",
        "directory",
    )
    QFileDialog.getOpenFileNames = static_method_kwargs_wrapper(
        QFileDialog.getOpenFileNames,
        "dir",
        "directory",
    )
    QFileDialog.getSaveFileName = static_method_kwargs_wrapper(
        QFileDialog.getSaveFileName,
        "dir",
        "directory",
    )

# Make `addAction` compatible with Qt6 >= 6.4
if PYQT5 or PYSIDE2 or parse(_qt_version) < parse("6.4"):

    class _QMenu(QMenu):
        old_add_action = QMenu.addAction

        def addAction(self, *args):
            return add_action(
                self,
                *args,
                old_add_action=_QMenu.old_add_action,
            )

    _menu_add_action = partialmethod(
        add_action,
        old_add_action=QMenu.addAction,
    )
    QMenu.addAction = _menu_add_action
    # Despite the previous line!
    if QMenu.addAction is not _menu_add_action:
        QMenu = _QMenu

    class _QToolBar(QToolBar):
        old_add_action = QToolBar.addAction

        def addAction(self, *args):
            return add_action(
                self,
                *args,
                old_add_action=_QToolBar.old_add_action,
            )

    _toolbar_add_action = partialmethod(
        add_action,
        old_add_action=QToolBar.addAction,
    )
    QToolBar.addAction = _toolbar_add_action
    # Despite the previous line!
    if QToolBar.addAction is not _toolbar_add_action:
        QToolBar = _QToolBar