Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 32935fd

Browse files
anntzertacaswell
authored andcommitted
Deprecate backend_qt.qApp.
This global has subtly different semantics from QtWidgets.QApplication.instance() (it is only updated when the private _create_qApp is called), and therefore seems not worth exposing.
1 parent e3c8195 commit 32935fd

File tree

2 files changed

+66
-59
lines changed

2 files changed

+66
-59
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
``backend_qt.qApp``
2+
~~~~~~~~~~~~~~~~~~~
3+
... is deprecated. Use ``QtWidgets.QApplication.instance()`` instead.

lib/matplotlib/backends/backend_qt.py

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -92,70 +92,73 @@
9292
}
9393

9494

95-
# make place holder
96-
qApp = None
95+
@_api.caching_module_getattr
96+
class __getattr__:
97+
qApp = _api.deprecated(
98+
"3.6", alternative="QtWidgets.QApplication.instance()")(
99+
property(lambda self: QtWidgets.QApplication.instance()))
97100

98101

102+
# lru_cache keeps a reference to the QApplication instance, keeping it from
103+
# being GC'd.
104+
@functools.lru_cache(1)
99105
def _create_qApp():
100-
"""
101-
Only one qApp can exist at a time, so check before creating one.
102-
"""
103-
global qApp
104-
105-
if qApp is None:
106-
app = QtWidgets.QApplication.instance()
107-
if app is None:
108-
# display_is_valid returns False only if on Linux and neither X11
109-
# nor Wayland display can be opened.
110-
if not mpl._c_internal_utils.display_is_valid():
111-
raise RuntimeError('Invalid DISPLAY variable')
112-
try:
113-
QtWidgets.QApplication.setAttribute(
114-
QtCore.Qt.AA_EnableHighDpiScaling)
115-
except AttributeError: # Only for Qt>=5.6, <6.
116-
pass
117-
118-
# Check to make sure a QApplication from a different major version
119-
# of Qt is not instantiated in the process
120-
if QT_API in {'PyQt6', 'PySide6'}:
121-
other_bindings = ('PyQt5', 'PySide2')
122-
elif QT_API in {'PyQt5', 'PySide2'}:
123-
other_bindings = ('PyQt6', 'PySide6')
124-
else:
125-
raise RuntimeError("Should never be here")
126-
127-
for binding in other_bindings:
128-
mod = sys.modules.get(f'{binding}.QtWidgets')
129-
if mod is not None and mod.QApplication.instance() is not None:
130-
other_core = sys.modules.get(f'{binding}.QtCore')
131-
_api.warn_external(
132-
f'Matplotlib is using {QT_API} which wraps '
133-
f'{QtCore.qVersion()} however an instantiated '
134-
f'QApplication from {binding} which wraps '
135-
f'{other_core.qVersion()} exists. Mixing Qt major '
136-
'versions may not work as expected.'
137-
)
138-
break
139-
try:
140-
QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
141-
QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
142-
except AttributeError: # Only for Qt>=5.14.
143-
pass
144-
qApp = QtWidgets.QApplication(["matplotlib"])
145-
if sys.platform == "darwin":
146-
image = str(cbook._get_data_path('images/matplotlib.svg'))
147-
icon = QtGui.QIcon(image)
148-
qApp.setWindowIcon(icon)
149-
qApp.lastWindowClosed.connect(qApp.quit)
150-
cbook._setup_new_guiapp()
106+
app = QtWidgets.QApplication.instance()
107+
108+
# Create a new QApplication and configure if if non exists yet, as only one
109+
# QApplication can exist at a time.
110+
if app is None:
111+
# display_is_valid returns False only if on Linux and neither X11
112+
# nor Wayland display can be opened.
113+
if not mpl._c_internal_utils.display_is_valid():
114+
raise RuntimeError('Invalid DISPLAY variable')
115+
116+
# Check to make sure a QApplication from a different major version
117+
# of Qt is not instantiated in the process
118+
if QT_API in {'PyQt6', 'PySide6'}:
119+
other_bindings = ('PyQt5', 'PySide2')
120+
elif QT_API in {'PyQt5', 'PySide2'}:
121+
other_bindings = ('PyQt6', 'PySide6')
151122
else:
152-
qApp = app
123+
raise RuntimeError("Should never be here")
124+
125+
for binding in other_bindings:
126+
mod = sys.modules.get(f'{binding}.QtWidgets')
127+
if mod is not None and mod.QApplication.instance() is not None:
128+
other_core = sys.modules.get(f'{binding}.QtCore')
129+
_api.warn_external(
130+
f'Matplotlib is using {QT_API} which wraps '
131+
f'{QtCore.qVersion()} however an instantiated '
132+
f'QApplication from {binding} which wraps '
133+
f'{other_core.qVersion()} exists. Mixing Qt major '
134+
'versions may not work as expected.'
135+
)
136+
break
137+
try:
138+
QtWidgets.QApplication.setAttribute(
139+
QtCore.Qt.AA_EnableHighDpiScaling)
140+
except AttributeError: # Only for Qt>=5.6, <6.
141+
pass
142+
try:
143+
QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
144+
QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
145+
except AttributeError: # Only for Qt>=5.14.
146+
pass
147+
app = QtWidgets.QApplication(["matplotlib"])
148+
if sys.platform == "darwin":
149+
image = str(cbook._get_data_path('images/matplotlib.svg'))
150+
icon = QtGui.QIcon(image)
151+
app.setWindowIcon(icon)
152+
app.lastWindowClosed.connect(app.quit)
153+
cbook._setup_new_guiapp()
153154

154155
try:
155-
qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps) # Only for Qt<6.
156+
app.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps) # Only for Qt<6.
156157
except AttributeError:
157158
pass
158159

160+
return app
161+
159162

160163
def _allow_super_init(__init__):
161164
"""
@@ -419,7 +422,7 @@ def _get_key(self, event):
419422

420423
def flush_events(self):
421424
# docstring inherited
422-
qApp.processEvents()
425+
QtWidgets.QApplication.instance().processEvents()
423426

424427
def start_event_loop(self, timeout=0):
425428
# docstring inherited
@@ -1022,7 +1025,7 @@ def trigger(self, *args):
10221025
class ToolCopyToClipboardQT(backend_tools.ToolCopyToClipboardBase):
10231026
def trigger(self, *args, **kwargs):
10241027
pixmap = self.canvas.grab()
1025-
qApp.clipboard().setPixmap(pixmap)
1028+
QtWidgets.QApplication.instance().clipboard().setPixmap(pixmap)
10261029

10271030

10281031
FigureManagerQT._toolbar2_class = NavigationToolbar2QT
@@ -1036,5 +1039,6 @@ class _BackendQT(_Backend):
10361039

10371040
@staticmethod
10381041
def mainloop():
1039-
with _maybe_allow_interrupt(qApp):
1040-
qt_compat._exec(qApp)
1042+
qapp = QtWidgets.QApplication.instance()
1043+
with _maybe_allow_interrupt(qapp):
1044+
qt_compat._exec(qapp)

0 commit comments

Comments
 (0)