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

Skip to content

Drop support for Qt<5.10. #24710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/api/next_api_changes/development/24710-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Support for Qt<5.10 has been dropped
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... as there are no wheels or conda packages that support both Qt 5.9 (or
older) and Python 3.8 (or newer).
4 changes: 4 additions & 0 deletions doc/devel/min_dep_policy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ Ghostscript, FFmpeg) support as old as practical. These can be difficult to
install for end-users and we want to be usable on as many systems as
possible. We will bump these on a case-by-case basis.

In the case of GUI frameworks for which we rely on Python bindings being
available, we will also drop support for bindings so old that they don't
support any Python version that we support.

.. _list-of-dependency-min-versions:

List of dependency versions
Expand Down
10 changes: 5 additions & 5 deletions lib/matplotlib/backends/backend_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
from . import qt_compat
from .qt_compat import (
QtCore, QtGui, QtWidgets, __version__, QT_API,
_enum, _to_int,
_devicePixelRatioF, _isdeleted, _setDevicePixelRatio,
_maybe_allow_interrupt
_enum, _to_int, _isdeleted, _maybe_allow_interrupt
)


Expand Down Expand Up @@ -220,7 +218,8 @@ def __init__(self, figure=None):
self.setPalette(palette)

def _update_pixel_ratio(self):
if self._set_device_pixel_ratio(_devicePixelRatioF(self)):
if self._set_device_pixel_ratio(
self.devicePixelRatioF() or 1): # rarely, devicePixelRatioF=0
# The easiest way to resize the canvas is to emit a resizeEvent
# since we implement all the logic for resizing the canvas for
# that event.
Expand Down Expand Up @@ -677,7 +676,8 @@ def _icon(self, name):
filename = str(path_large if path_large.exists() else path_regular)

pm = QtGui.QPixmap(filename)
_setDevicePixelRatio(pm, _devicePixelRatioF(self))
pm.setDevicePixelRatio(
self.devicePixelRatioF() or 1) # rarely, devicePixelRatioF=0
if self.palette().color(self.backgroundRole()).value() < 128:
icon_color = self.palette().color(self.foregroundRole())
mask = pm.createMaskFromColor(
Expand Down
15 changes: 4 additions & 11 deletions lib/matplotlib/backends/backend_qtagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

from matplotlib.transforms import Bbox

from .qt_compat import QT_API, _enum, _setDevicePixelRatio
from .. import cbook
from .qt_compat import QT_API, _enum
from .backend_agg import FigureCanvasAgg
from .backend_qt import QtCore, QtGui, _BackendQT, FigureCanvasQT
from .backend_qt import ( # noqa: F401 # pylint: disable=W0611
Expand Down Expand Up @@ -50,22 +49,16 @@ def paintEvent(self, event):
bbox = Bbox([[left, bottom], [right, top]])
buf = memoryview(self.copy_from_bbox(bbox))

fmts = _enum("QtGui.QImage.Format")
if hasattr(fmts, "Format_RGBA8888"):
fmt = fmts.Format_RGBA8888
else: # Qt<=5.1 support.
fmt = fmts.Format_ARGB32_Premultiplied
buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(buf)

if QT_API == "PyQt6":
from PyQt6 import sip
ptr = int(sip.voidptr(buf))
else:
ptr = buf

painter.eraseRect(rect) # clear the widget canvas
qimage = QtGui.QImage(ptr, buf.shape[1], buf.shape[0], fmt)
_setDevicePixelRatio(qimage, self.device_pixel_ratio)
qimage = QtGui.QImage(ptr, buf.shape[1], buf.shape[0],
_enum("QtGui.QImage.Format").Format_RGBA8888)
qimage.setDevicePixelRatio(self.device_pixel_ratio)
# set origin using original QT coordinates
origin = QtCore.QPoint(rect.left(), rect.top())
painter.drawImage(origin, qimage)
Expand Down
9 changes: 4 additions & 5 deletions lib/matplotlib/backends/backend_qtcairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .backend_cairo import cairo, FigureCanvasCairo
from .backend_qt import QtCore, QtGui, _BackendQT, FigureCanvasQT
from .qt_compat import QT_API, _enum, _setDevicePixelRatio
from .qt_compat import QT_API, _enum


class FigureCanvasQTCairo(FigureCanvasCairo, FigureCanvasQT):
Expand Down Expand Up @@ -31,10 +31,9 @@ def paintEvent(self, event):
_enum("QtGui.QImage.Format").Format_ARGB32_Premultiplied)
# Adjust the buf reference count to work around a memory leak bug in
# QImage under PySide.
if QT_API in ('PySide', 'PySide2'):
if QtCore.__version_info__ < (5, 12):
ctypes.c_long.from_address(id(buf)).value = 1
_setDevicePixelRatio(qimage, self.device_pixel_ratio)
if QT_API == "PySide2" and QtCore.__version_info__ < (5, 12):
ctypes.c_long.from_address(id(buf)).value = 1
qimage.setDevicePixelRatio(self.device_pixel_ratio)
painter = QtGui.QPainter(self)
painter.eraseRect(event.rect())
painter.drawImage(0, 0, qimage)
Expand Down
41 changes: 9 additions & 32 deletions lib/matplotlib/backends/qt_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ def _isdeleted(obj):
(_setup_pyqt5plus, QT_API_PYQT5),
(_setup_pyqt5plus, QT_API_PYSIDE2),
]

for _setup, QT_API in _candidates:
try:
_setup()
Expand All @@ -138,13 +137,21 @@ def _isdeleted(obj):
.format(", ".join(_ETS.values())))
else: # We should not get there.
raise AssertionError(f"Unexpected QT_API: {QT_API}")
_version_info = tuple(QtCore.QLibraryInfo.version().segments())


if _version_info < (5, 10):
raise ImportError(
f"The Qt version imported is "
f"{QtCore.QLibraryInfo.version().toString()} but Matplotlib requires "
f"Qt>=5.10")


# Fixes issues with Big Sur
# https://bugreports.qt.io/browse/QTBUG-87014, fixed in qt 5.15.2
if (sys.platform == 'darwin' and
parse_version(platform.mac_ver()[0]) >= parse_version("10.16") and
QtCore.QLibraryInfo.version().segments() <= [5, 15, 2]):
_version_info < (5, 15, 2)):
os.environ.setdefault("QT_MAC_WANTS_LAYER", "1")


Expand All @@ -167,36 +174,6 @@ def _exec(obj):
obj.exec() if hasattr(obj, "exec") else obj.exec_()


def _devicePixelRatioF(obj):
"""
Return obj.devicePixelRatioF() with graceful fallback for older Qt.

This can be replaced by the direct call when we require Qt>=5.6.
"""
try:
# Not available on Qt<5.6
return obj.devicePixelRatioF() or 1
except AttributeError:
pass
try:
# Not available on older Qt5.
# self.devicePixelRatio() returns 0 in rare cases
return obj.devicePixelRatio() or 1
except AttributeError:
return 1


def _setDevicePixelRatio(obj, val):
"""
Call obj.setDevicePixelRatio(val) with graceful fallback for older Qt.

This can be replaced by the direct call when we require Qt>=5.6.
"""
if hasattr(obj, 'setDevicePixelRatio'):
# Not available on older Qt5.
obj.setDevicePixelRatio(val)


@contextlib.contextmanager
def _maybe_allow_interrupt(qapp):
"""
Expand Down