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

Skip to content

Commit 197d944

Browse files
anntzerQuLogic
authored andcommitted
Single qt backend.
Testing all qt bindings actually caught the fact that PySide makes the backend not thread-safe. Co-authored-by: Elliott Sales de Andrade <[email protected]>
1 parent 953913f commit 197d944

22 files changed

Lines changed: 1318 additions & 1259 deletions

.github/workflows/tests.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ jobs:
179179
python -c 'import PySide2.QtCore' &&
180180
echo 'PySide2 is available' ||
181181
echo 'PySide2 is not available'
182+
python -mpip install --upgrade pyqt6 &&
183+
python -c 'import PyQt6.QtCore' &&
184+
echo 'PyQt6 is available' ||
185+
echo 'PyQt6 is not available'
186+
python -mpip install --upgrade pyside6 &&
187+
python -c 'import PySide6.QtCore' &&
188+
echo 'PySide6 is available' ||
189+
echo 'PySide6 is not available'
182190
fi
183191
python -m pip install --upgrade \
184192
-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-$(lsb_release -r -s) \

doc/devel/dependencies.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Matplotlib figures can be rendered to various user interfaces. See
4141
and the capabilities they provide.
4242

4343
* Tk_ (>= 8.3, != 8.6.0 or 8.6.1) [#]_: for the Tk-based backends.
44-
* PyQt5_ or PySide2_: for the Qt5-based backends.
44+
* PyQt6_, PySide6_, PyQt5_, or PySide2_: for the Qt-based backends.
4545
* PyGObject_: for the GTK3-based backends [#]_.
4646
* wxPython_ (>= 4) [#]_: for the wx-based backends.
4747
* pycairo_ (>= 1.11.0) or cairocffi_ (>= 0.8): for the GTK3 and/or cairo-based
@@ -51,6 +51,8 @@ and the capabilities they provide.
5151
.. _Tk: https://docs.python.org/3/library/tk.html
5252
.. _PyQt5: https://pypi.org/project/PyQt5/
5353
.. _PySide2: https://pypi.org/project/PySide2/
54+
.. _PyQt6: https://pypi.org/project/PyQt6/
55+
.. _PySide6: https://pypi.org/project/PySide6/
5456
.. _PyGObject: https://pygobject.readthedocs.io/en/latest/
5557
.. _wxPython: https://www.wxpython.org/
5658
.. _pycairo: https://pycairo.readthedocs.io/en/latest/

doc/users/interactive.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ it also ensures that the GUI toolkit event loop is properly integrated
6363
with the command line (see :ref:`cp_integration`).
6464

6565
In this example, we create and modify a figure via an IPython prompt.
66-
The figure displays in a Qt5Agg GUI window. To configure the integration
66+
The figure displays in a QtAgg GUI window. To configure the integration
6767
and enable :ref:`interactive mode <controlling-interactive>` use the
6868
``%matplotlib`` magic:
6969

@@ -72,7 +72,7 @@ and enable :ref:`interactive mode <controlling-interactive>` use the
7272
::
7373

7474
In [1]: %matplotlib
75-
Using matplotlib backend: Qt5Agg
75+
Using matplotlib backend: QtAgg
7676

7777
In [2]: import matplotlib.pyplot as plt
7878

examples/user_interfaces/embedding_in_qt_sgskip.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
===============
55
66
Simple Qt application embedding Matplotlib canvases. This program will work
7-
equally well using Qt4 and Qt5. Either version of Qt can be selected (for
8-
example) by setting the ``MPLBACKEND`` environment variable to "Qt4Agg" or
9-
"Qt5Agg", or by first importing the desired version of PyQt.
7+
equally well using any Qt binding (PyQt6, PySide6, PyQt5, PySide2). The
8+
binding can be selected by setting the ``QT_API`` environment variable to the
9+
binding name, or by first importing it.
1010
"""
1111

1212
import sys
1313
import time
1414

1515
import numpy as np
1616

17-
from matplotlib.backends.qt_compat import QtCore, QtWidgets
18-
from matplotlib.backends.backend_qt5agg import (
17+
from matplotlib.backends.qt_compat import QtWidgets
18+
from matplotlib.backends.backend_qtagg import (
1919
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
2020
from matplotlib.figure import Figure
2121

@@ -28,13 +28,15 @@ def __init__(self):
2828
layout = QtWidgets.QVBoxLayout(self._main)
2929

3030
static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
31+
# Ideally one would use self.addToolBar here, but it is slightly
32+
# incompatible between PyQt6 and other bindings, so we just add the
33+
# toolbar as a plain widget instead.
34+
layout.addWidget(NavigationToolbar(static_canvas, self))
3135
layout.addWidget(static_canvas)
32-
self.addToolBar(NavigationToolbar(static_canvas, self))
3336

3437
dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
3538
layout.addWidget(dynamic_canvas)
36-
self.addToolBar(QtCore.Qt.BottomToolBarArea,
37-
NavigationToolbar(dynamic_canvas, self))
39+
layout.addWidget(NavigationToolbar(dynamic_canvas, self))
3840

3941
self._static_ax = static_canvas.figure.subplots()
4042
t = np.linspace(0, 10, 501)
@@ -66,4 +68,4 @@ def _update_canvas(self):
6668
app.show()
6769
app.activateWindow()
6870
app.raise_()
69-
qapp.exec_()
71+
qapp.exec()

lib/matplotlib/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,9 +1100,8 @@ def use(backend, *, force=True):
11001100
backend names, which are case-insensitive:
11011101
11021102
- interactive backends:
1103-
GTK3Agg, GTK3Cairo, MacOSX, nbAgg,
1104-
Qt5Agg, Qt5Cairo,
1105-
TkAgg, TkCairo, WebAgg, WX, WXAgg, WXCairo
1103+
GTK3Agg, GTK3Cairo, MacOSX, nbAgg, QtAgg, QtCairo,
1104+
TkAgg, TkCairo, WebAgg, WX, WXAgg, WXCairo, Qt5Agg, Qt5Cairo
11061105
11071106
- non-interactive backends:
11081107
agg, cairo, pdf, pgf, ps, svg, template

lib/matplotlib/backend_bases.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,14 @@ def _safe_pyplot_import():
9898
current_framework = cbook._get_running_interactive_framework()
9999
if current_framework is None:
100100
raise # No, something else went wrong, likely with the install...
101-
backend_mapping = {'qt5': 'qt5agg',
102-
'gtk3': 'gtk3agg',
103-
'wx': 'wxagg',
104-
'tk': 'tkagg',
105-
'macosx': 'macosx',
106-
'headless': 'agg'}
101+
backend_mapping = {
102+
'qt': 'qtagg',
103+
'gtk3': 'gtk3agg',
104+
'wx': 'wxagg',
105+
'tk': 'tkagg',
106+
'macosx': 'macosx',
107+
'headless': 'agg',
108+
}
107109
backend = backend_mapping[current_framework]
108110
rcParams["backend"] = mpl.rcParamsOrig["backend"] = backend
109111
import matplotlib.pyplot as plt # Now this should succeed.
@@ -1662,7 +1664,7 @@ class FigureCanvasBase:
16621664
A high-level figure instance.
16631665
"""
16641666

1665-
# Set to one of {"qt5", "gtk3", "wx", "tk", "macosx"} if an
1667+
# Set to one of {"qt", "gtk3", "wx", "tk", "macosx"} if an
16661668
# interactive framework is required, or None otherwise.
16671669
required_interactive_framework = None
16681670

@@ -1738,7 +1740,7 @@ def _fix_ipython_backend2gui(cls):
17381740
# don't break on our side.
17391741
return
17401742
rif = getattr(cls, "required_interactive_framework", None)
1741-
backend2gui_rif = {"qt5": "qt", "gtk3": "gtk3",
1743+
backend2gui_rif = {"qt": "qt", "gtk3": "gtk3",
17421744
"wx": "wx", "macosx": "osx"}.get(rif)
17431745
if backend2gui_rif:
17441746
if _is_non_interactive_terminal_ipython(ip):

0 commit comments

Comments
 (0)