1import ctypes 2 3from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo 4from .backend_qt5 import QtCore, QtGui, _BackendQT5, FigureCanvasQT 5from .qt_compat import QT_API, _setDevicePixelRatio 6 7 8class FigureCanvasQTCairo(FigureCanvasQT, FigureCanvasCairo): 9 def __init__(self, figure=None): 10 super().__init__(figure=figure) 11 self._renderer = RendererCairo(self.figure.dpi) 12 self._renderer.set_width_height(-1, -1) # Invalid values. 13 14 def draw(self): 15 if hasattr(self._renderer.gc, "ctx"): 16 self.figure.draw(self._renderer) 17 super().draw() 18 19 def paintEvent(self, event): 20 dpi_ratio = self._dpi_ratio 21 width = int(dpi_ratio * self.width()) 22 height = int(dpi_ratio * self.height()) 23 if (width, height) != self._renderer.get_canvas_width_height(): 24 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) 25 self._renderer.set_ctx_from_surface(surface) 26 self._renderer.set_width_height(width, height) 27 self.figure.draw(self._renderer) 28 buf = self._renderer.gc.ctx.get_target().get_data() 29 qimage = QtGui.QImage(buf, width, height, 30 QtGui.QImage.Format_ARGB32_Premultiplied) 31 # Adjust the buf reference count to work around a memory leak bug in 32 # QImage under PySide on Python 3. 33 if QT_API == 'PySide': 34 ctypes.c_long.from_address(id(buf)).value = 1 35 _setDevicePixelRatio(qimage, dpi_ratio) 36 painter = QtGui.QPainter(self) 37 painter.eraseRect(event.rect()) 38 painter.drawImage(0, 0, qimage) 39 self._draw_rect_callback(painter) 40 painter.end() 41 42 43@_BackendQT5.export 44class _BackendQT5Cairo(_BackendQT5): 45 FigureCanvas = FigureCanvasQTCairo 46