def paintEvent(self, event): if self._update_dpi(): return # We always repaint the full canvas (doing otherwise would require an # additional copy of the buffer into a contiguous block, so it's not # clear it would be faster). buf = _util.cairo_to_premultiplied_argb32( self.get_renderer(_ensure_drawn=True)._get_buffer()) height, width, _ = buf.shape # The image buffer is not necessarily contiguous, but the padding # in the ARGB32 case (each scanline is 32-bit aligned) happens to # match what QImage requires; in the RGBA128F case the documented Qt # requirement does not seem necessary? qimage = QtGui.QImage(buf, width, height, QtGui.QImage.Format_ARGB32_Premultiplied) try: qimage_setDevicePixelRatioF = qimage.setDevicePixelRatioF except AttributeError: try: qimage_setDevicePixelRatioF = qimage.setDevicePixelRatio except AttributeError: def qimage_setDevicePixelRatioF(scaleFactor): pass qimage_setDevicePixelRatioF(self._dpi_ratio) # FIXME[PySide{,2}]: https://bugreports.qt.io/browse/PYSIDE-140 if qt_compat.QT_API.startswith("PySide"): ctypes.c_long.from_address(id(buf)).value -= 1 painter = QtGui.QPainter(self) painter.eraseRect(self.rect()) painter.drawImage(0, 0, qimage) self._draw_rect_callback(painter) painter.end()
def paintEvent(self, event): if self._update_dpi(): return # We always repaint the full canvas (doing otherwise would require an # additional copy of the buffer into a contiguous block, so it's not # clear it would be faster). buf = self.get_renderer(_draw_if_new=True)._get_buffer() address, _ = buf.__array_interface__["data"] height, width, _ = buf.shape # The image buffer is not necessarily contiguous, but the padding in # the ARGB32 case (each scanline is 32-bit aligned) happens to match # what QImage requires. qimage = QtGui.QImage(address, width, height, QtGui.QImage.Format_ARGB32_Premultiplied) qimage.setDevicePixelRatio(self._dpi_ratio) painter = QtGui.QPainter(self) painter.eraseRect(self.rect()) painter.drawImage(0, 0, qimage) self._draw_rect_callback(painter) painter.end()
def paintEvent(self, event): if self._update_dpi(): return # We always repaint the full canvas (doing otherwise would require an # additional copy of the buffer into a contiguous block, so it's not # clear it would be faster). buf = self.get_renderer(_draw_if_new=True)._get_buffer() height, width, _ = buf.shape # The image buffer is not necessarily contiguous, but the padding in # the ARGB32 case (each scanline is 32-bit aligned) happens to match # what QImage requires. qimage = QtGui.QImage(buf, width, height, QtGui.QImage.Format_ARGB32_Premultiplied) getattr(qimage, "setDevicePixelRatio", lambda _: None)(self._dpi_ratio) # FIXME[PySide{,2}]: https://bugreports.qt.io/browse/PYSIDE-140 if qt_compat.QT_API.startswith("PySide"): ctypes.c_long.from_address(id(buf)).value -= 1 painter = QtGui.QPainter(self) painter.eraseRect(self.rect()) painter.drawImage(0, 0, qimage) self._draw_rect_callback(painter) painter.end()
def paintEvent(self, e): """ Copy the image from the Agg canvas to the qt.drawable. In Qt, all drawing should be done inside of here when a widget is shown onscreen. """ # FigureCanvasQT.paintEvent(self, e) if DEBUG: print('FigureCanvasQtAgg.paintEvent: ', self, self.get_width_height()) if self.blitbox is None: # matplotlib is in rgba byte order. QImage wants to put the bytes # into argb format and is in a 4 byte unsigned int. Little endian # system is LSB first and expects the bytes in reverse order # (bgra). if QtCore.QSysInfo.ByteOrder == QtCore.QSysInfo.LittleEndian: stringBuffer = self.renderer._renderer.tostring_bgra() else: stringBuffer = self.renderer._renderer.tostring_argb() refcnt = sys.getrefcount(stringBuffer) # convert the Agg rendered image -> qImage qImage = QtGui.QImage(stringBuffer, self.renderer.width, self.renderer.height, QtGui.QImage.Format_ARGB32) # get the rectangle for the image rect = qImage.rect() p = QtGui.QPainter(self) # reset the image area of the canvas to be the back-ground color p.eraseRect(rect) # draw the rendered image on to the canvas p.drawPixmap(QtCore.QPoint(0, 0), QtGui.QPixmap.fromImage(qImage)) # draw the zoom rectangle to the QPainter if self._drawRect is not None: p.setPen(QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.DotLine)) x, y, w, h = self._drawRect p.drawRect(x, y, w, h) p.end() # This works around a bug in PySide 1.1.2 on Python 3.x, # where the reference count of stringBuffer is incremented # but never decremented by QImage. # TODO: revert PR #1323 once the issue is fixed in PySide. del qImage if refcnt != sys.getrefcount(stringBuffer): _decref(stringBuffer) else: bbox = self.blitbox l, b, r, t = bbox.extents w = int(r) - int(l) h = int(t) - int(b) t = int(b) + h reg = self.copy_from_bbox(bbox) stringBuffer = reg.to_string_argb() qImage = QtGui.QImage(stringBuffer, w, h, QtGui.QImage.Format_ARGB32) pixmap = QtGui.QPixmap.fromImage(qImage) p = QtGui.QPainter(self) p.drawPixmap(QtCore.QPoint(l, self.renderer.height - t), pixmap) p.end() self.blitbox = None self._drawRect = None