Skip to content

Cairo rendering for Qt5 #8771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Prev Previous commit
Next Next commit
Qt dpi handling should be renderer-agnostic.
  • Loading branch information
anntzer committed Jan 9, 2018
commit 5087c055fea96dead4ab1c6c8e647def16828fbb
21 changes: 21 additions & 0 deletions lib/matplotlib/backends/backend_qt5.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,26 @@ def _dpi_ratio(self):
except AttributeError:
return 1

def _update_dpi(self):
# As described in __init__ above, we need to be careful in cases with
# mixed resolution displays if dpi_ratio is changing between painting
# events.
# Return whether we triggered a resizeEvent (and thus a paintEvent)
# from within this function.
if self._dpi_ratio != self._dpi_ratio_prev:
# We need to update the figure DPI.
self._update_figure_dpi()
self._dpi_ratio_prev = self._dpi_ratio
# The easiest way to resize the canvas is to emit a resizeEvent
# since we implement all the logic for resizing the canvas for
# that event.
event = QtGui.QResizeEvent(self.size(), self.size())
self.resizeEvent(event)
# resizeEvent triggers a paintEvent itself, so we exit this one
# (after making sure that the event is immediately handled).
return True
return False

def get_width_height(self):
w, h = FigureCanvasBase.get_width_height(self)
return int(w / self._dpi_ratio), int(h / self._dpi_ratio)
Expand Down Expand Up @@ -489,6 +509,7 @@ def draw_idle(self):
def _draw_idle(self):
if self.height() < 0 or self.width() < 0:
self._draw_pending = False
if not self._draw_pending:
return
try:
self.draw()
Expand Down
27 changes: 5 additions & 22 deletions lib/matplotlib/backends/backend_qt5agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,13 @@ def paintEvent(self, e):
In Qt, all drawing should be done inside of here when a widget is
shown onscreen.
"""
# if there is a pending draw, run it now as we need the updated render
# to paint the widget
if self._agg_draw_pending:
self.__draw_idle_agg()
# As described in __init__ above, we need to be careful in cases with
# mixed resolution displays if dpi_ratio is changing between painting
# events.
if self._dpi_ratio != self._dpi_ratio_prev:
# We need to update the figure DPI
self._update_figure_dpi()
self._dpi_ratio_prev = self._dpi_ratio
# The easiest way to resize the canvas is to emit a resizeEvent
# since we implement all the logic for resizing the canvas for
# that event.
event = QtGui.QResizeEvent(self.size(), self.size())
# We use self.resizeEvent here instead of QApplication.postEvent
# since the latter doesn't guarantee that the event will be emitted
# straight away, and this causes visual delays in the changes.
self.resizeEvent(event)
# resizeEvent triggers a paintEvent itself, so we exit this one.
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 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

Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/backends/backend_qt5cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def __init__(self, figure):
self._renderer = backend_cairo.RendererCairo(self.figure.dpi)

def paintEvent(self, event):
self._update_dpi()
width = self.width()
height = self.height()
surface = backend_cairo.cairo.ImageSurface(
Expand Down