diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index 9b924ce8ecb1..4e5cd5b18e10 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -249,6 +249,15 @@ def __init__(self, figure): # Key auto-repeat enabled by default self._keyautorepeat = True + # In cases with mixed resolution displays, we need to be careful if the + # dpi_ratio changes - in this case we need to resize the canvas + # accordingly. We could watch for screenChanged events from Qt, but + # the issue is that we can't guarantee this will be emitted *before* + # the first paintEvent for the canvas, so instead we keep track of the + # dpi_ratio value here and in paintEvent we resize the canvas if + # needed. + self._dpi_ratio_prev = None + @property def _dpi_ratio(self): # Not available on Qt4 or some older Qt5. @@ -342,6 +351,10 @@ def keyAutoRepeat(self, val): self._keyautorepeat = bool(val) def resizeEvent(self, event): + # _dpi_ratio_prev will be set the first time the canvas is painted, and + # the rendered buffer is useless before anyways. + if self._dpi_ratio_prev is None: + return w = event.size().width() * self._dpi_ratio h = event.size().height() * self._dpi_ratio dpival = self.figure.dpi diff --git a/lib/matplotlib/backends/backend_qt5agg.py b/lib/matplotlib/backends/backend_qt5agg.py index 78d9fdada4f6..bb5bd64396c7 100644 --- a/lib/matplotlib/backends/backend_qt5agg.py +++ b/lib/matplotlib/backends/backend_qt5agg.py @@ -14,7 +14,7 @@ from .backend_agg import FigureCanvasAgg from .backend_qt5 import ( - QtCore, QtGui, _BackendQT5, FigureCanvasQT, FigureManagerQT, + QtCore, QtGui, QtWidgets, _BackendQT5, FigureCanvasQT, FigureManagerQT, NavigationToolbar2QT, backend_version) from .qt_compat import QT_API @@ -38,15 +38,6 @@ def __init__(self, figure): self._bbox_queue = [] self._drawRect = None - # In cases with mixed resolution displays, we need to be careful if the - # dpi_ratio changes - in this case we need to resize the canvas - # accordingly. We could watch for screenChanged events from Qt, but - # the issue is that we can't guarantee this will be emitted *before* - # the first paintEvent for the canvas, so instead we keep track of the - # dpi_ratio value here and in paintEvent we resize the canvas if - # needed. - self._dpi_ratio_prev = None - def drawRectangle(self, rect): if rect is not None: self._drawRect = [pt / self._dpi_ratio for pt in rect] @@ -66,18 +57,13 @@ def paintEvent(self, e): shown onscreen. """ - # if the canvas does not have a renderer, then give up and wait for - # FigureCanvasAgg.draw(self) to be called - if not hasattr(self, 'renderer'): - return - # As described in __init__ above, we need to be careful in cases with # mixed resolution displays if dpi_ratio is changing between painting # events. - if (self._dpi_ratio_prev is None or - self._dpi_ratio != self._dpi_ratio_prev): + if self._dpi_ratio != self._dpi_ratio_prev: # We need to update the figure DPI self._update_figure_dpi() + self._dpi_ratio_prev = self._dpi_ratio # 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. @@ -86,7 +72,14 @@ def paintEvent(self, e): # since the latter doesn't guarantee that the event will be emitted # straight away, and this causes visual delays in the changes. self.resizeEvent(event) - self._dpi_ratio_prev = self._dpi_ratio + QtWidgets.QApplication.instance().processEvents() + # resizeEvent triggers a paintEvent itself, so we exit this one. + return + + # if the canvas does not have a renderer, then give up and wait for + # FigureCanvasAgg.draw(self) to be called + if not hasattr(self, 'renderer'): + return painter = QtGui.QPainter(self)