backend_qtcairo.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import ctypes
  2. from .backend_cairo import cairo, FigureCanvasCairo
  3. from .backend_qt import _BackendQT, FigureCanvasQT
  4. from .qt_compat import QT_API, QtCore, QtGui
  5. class FigureCanvasQTCairo(FigureCanvasCairo, FigureCanvasQT):
  6. def draw(self):
  7. if hasattr(self._renderer.gc, "ctx"):
  8. self._renderer.dpi = self.figure.dpi
  9. self.figure.draw(self._renderer)
  10. super().draw()
  11. def paintEvent(self, event):
  12. width = int(self.device_pixel_ratio * self.width())
  13. height = int(self.device_pixel_ratio * self.height())
  14. if (width, height) != self._renderer.get_canvas_width_height():
  15. surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
  16. self._renderer.set_context(cairo.Context(surface))
  17. self._renderer.dpi = self.figure.dpi
  18. self.figure.draw(self._renderer)
  19. buf = self._renderer.gc.ctx.get_target().get_data()
  20. if QT_API == "PyQt6":
  21. from PyQt6 import sip
  22. ptr = int(sip.voidptr(buf))
  23. else:
  24. ptr = buf
  25. qimage = QtGui.QImage(
  26. ptr, width, height,
  27. QtGui.QImage.Format.Format_ARGB32_Premultiplied)
  28. # Adjust the buf reference count to work around a memory leak bug in
  29. # QImage under PySide.
  30. if QT_API == "PySide2" and QtCore.__version_info__ < (5, 12):
  31. ctypes.c_long.from_address(id(buf)).value = 1
  32. qimage.setDevicePixelRatio(self.device_pixel_ratio)
  33. painter = QtGui.QPainter(self)
  34. painter.eraseRect(event.rect())
  35. painter.drawImage(0, 0, qimage)
  36. self._draw_rect_callback(painter)
  37. painter.end()
  38. @_BackendQT.export
  39. class _BackendQTCairo(_BackendQT):
  40. FigureCanvas = FigureCanvasQTCairo