demo + utils venv
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""
|
||||
Render to qt from agg
|
||||
"""
|
||||
|
||||
import ctypes
|
||||
|
||||
from matplotlib.transforms import Bbox
|
||||
|
||||
from .. import cbook
|
||||
from .backend_agg import FigureCanvasAgg
|
||||
from .backend_qt5 import (
|
||||
QtCore, QtGui, QtWidgets, _BackendQT5, FigureCanvasQT, FigureManagerQT,
|
||||
NavigationToolbar2QT, backend_version)
|
||||
from .qt_compat import QT_API
|
||||
|
||||
|
||||
class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT):
|
||||
|
||||
def __init__(self, figure):
|
||||
# Must pass 'figure' as kwarg to Qt base class.
|
||||
super().__init__(figure=figure)
|
||||
|
||||
def paintEvent(self, event):
|
||||
"""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.
|
||||
"""
|
||||
if self._update_dpi():
|
||||
# The dpi update triggered its own paintEvent.
|
||||
return
|
||||
self._draw_idle() # Only does something if a draw is pending.
|
||||
|
||||
# if the canvas does not have a renderer, then give up and wait for
|
||||
# FigureCanvasAgg.draw(self) to be called
|
||||
if not hasattr(self, 'renderer'):
|
||||
return
|
||||
|
||||
painter = QtGui.QPainter(self)
|
||||
|
||||
if self._erase_before_paint:
|
||||
painter.eraseRect(self.rect())
|
||||
self._erase_before_paint = False
|
||||
|
||||
rect = event.rect()
|
||||
left = rect.left()
|
||||
top = rect.top()
|
||||
width = rect.width()
|
||||
height = rect.height()
|
||||
# See documentation of QRect: bottom() and right() are off by 1, so use
|
||||
# left() + width() and top() + height().
|
||||
bbox = Bbox(
|
||||
[[left, self.renderer.height - (top + height * self._dpi_ratio)],
|
||||
[left + width * self._dpi_ratio, self.renderer.height - top]])
|
||||
reg = self.copy_from_bbox(bbox)
|
||||
buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
|
||||
memoryview(reg))
|
||||
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)
|
||||
origin = QtCore.QPoint(left, top)
|
||||
painter.drawImage(origin / self._dpi_ratio, 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()
|
||||
|
||||
def blit(self, bbox=None):
|
||||
"""Blit the region in bbox.
|
||||
"""
|
||||
# If bbox is None, blit the entire canvas. Otherwise
|
||||
# blit only the area defined by the bbox.
|
||||
if bbox is None and self.figure:
|
||||
bbox = self.figure.bbox
|
||||
|
||||
# repaint uses logical pixels, not physical pixels like the renderer.
|
||||
l, b, w, h = [pt / self._dpi_ratio for pt in bbox.bounds]
|
||||
t = b + h
|
||||
self.repaint(l, self.renderer.height / self._dpi_ratio - t, w, h)
|
||||
|
||||
def print_figure(self, *args, **kwargs):
|
||||
super().print_figure(*args, **kwargs)
|
||||
self.draw()
|
||||
|
||||
|
||||
@_BackendQT5.export
|
||||
class _BackendQT5Agg(_BackendQT5):
|
||||
FigureCanvas = FigureCanvasQTAgg
|
||||
Reference in New Issue
Block a user