diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index 1265479d2ead..0642dcfab87a 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -486,7 +486,7 @@ def drawRectangle(self, rect): # Draw the zoom rectangle to the QPainter. _draw_rect_callback needs # to be called at the end of paintEvent. if rect is not None: - x0, y0, w, h = [pt / self._dpi_ratio for pt in rect] + x0, y0, w, h = [int(pt / self._dpi_ratio) for pt in rect] x1 = x0 + w y1 = y0 + h def _draw_rect_callback(painter): diff --git a/lib/matplotlib/backends/backend_qt5agg.py b/lib/matplotlib/backends/backend_qt5agg.py index 2d4d636d4018..11b60378ac39 100644 --- a/lib/matplotlib/backends/backend_qt5agg.py +++ b/lib/matplotlib/backends/backend_qt5agg.py @@ -38,45 +38,46 @@ def paintEvent(self, event): return painter = QtGui.QPainter(self) - - # See documentation of QRect: bottom() and right() are off by 1, so use - # left() + width() and top() + height(). - rect = event.rect() - # scale rect dimensions using the screen dpi ratio to get - # correct values for the Figure coordinates (rather than QT5's coords) - width = rect.width() * self._dpi_ratio - height = rect.height() * self._dpi_ratio - left, top = self.mouseEventCoords(rect.topLeft()) - # shift the "top" by the height of the image to get the - # correct corner for our coordinate system - bottom = top - height - # same with the right side of the image - right = left + width - # create a buffer using the image bounding box - bbox = Bbox([[left, bottom], [right, top]]) - reg = self.copy_from_bbox(bbox) - buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32( - memoryview(reg)) - - # clear the widget canvas - painter.eraseRect(rect) - - qimage = QtGui.QImage(buf, buf.shape[1], buf.shape[0], - QtGui.QImage.Format_ARGB32_Premultiplied) - if hasattr(qimage, 'setDevicePixelRatio'): - # Not available on Qt4 or some older Qt5. - qimage.setDevicePixelRatio(self._dpi_ratio) - # set origin using original QT coordinates - origin = QtCore.QPoint(rect.left(), rect.top()) - painter.drawImage(origin, qimage) - # Adjust the buf reference count to work around a memory - # leak bug in QImage under PySide on Python 3. - if QT_API in ('PySide', 'PySide2'): - ctypes.c_long.from_address(id(buf)).value = 1 - - self._draw_rect_callback(painter) - - painter.end() + try: + # See documentation of QRect: bottom() and right() are off + # by 1, so use left() + width() and top() + height(). + rect = event.rect() + # scale rect dimensions using the screen dpi ratio to get + # correct values for the Figure coordinates (rather than + # QT5's coords) + width = rect.width() * self._dpi_ratio + height = rect.height() * self._dpi_ratio + left, top = self.mouseEventCoords(rect.topLeft()) + # shift the "top" by the height of the image to get the + # correct corner for our coordinate system + bottom = top - height + # same with the right side of the image + right = left + width + # create a buffer using the image bounding box + bbox = Bbox([[left, bottom], [right, top]]) + reg = self.copy_from_bbox(bbox) + buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32( + memoryview(reg)) + + # clear the widget canvas + painter.eraseRect(rect) + + qimage = QtGui.QImage(buf, buf.shape[1], buf.shape[0], + QtGui.QImage.Format_ARGB32_Premultiplied) + if hasattr(qimage, 'setDevicePixelRatio'): + # Not available on Qt4 or some older Qt5. + qimage.setDevicePixelRatio(self._dpi_ratio) + # set origin using original QT coordinates + origin = QtCore.QPoint(rect.left(), rect.top()) + painter.drawImage(origin, qimage) + # Adjust the buf reference count to work around a memory + # leak bug in QImage under PySide on Python 3. + if QT_API in ('PySide', 'PySide2'): + ctypes.c_long.from_address(id(buf)).value = 1 + + self._draw_rect_callback(painter) + finally: + painter.end() def print_figure(self, *args, **kwargs): super().print_figure(*args, **kwargs)