backend_qt5cairo.py 1.8 KB

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