Skip to content
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