8000 FIX: prevent recursive draws with plt.ion not in IPython with qt5agg · matplotlib/matplotlib@36448e8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 36448e8

Browse files
committed
FIX: prevent recursive draws with plt.ion not in IPython with qt5agg
In 9b8a944 the latch logic was moved above the call to `self.draw` to de-latch the call to `__draw_idle_agg` in `paintEvent` to protect against `blit` calls during a draw. However, this now fails to properly latch the base draw so with `plt.ion` (not in IPython) the stale callback will cause a (possibly infinite) recursion in the draw due to stale being set as part of the draw call (which will re-trigger the draw). This adds a second flag to track if we are currently rendering and bail. closes #10140
1 parent 008da38 commit 36448e8

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

lib/matplotlib/backends/backend_qt5agg.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def __init__(self, figure):
3535
super(FigureCanvasQTAggBase, self).__init__(figure=figure)
3636
self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
3737
self._agg_draw_pending = False
38+
self._agg_is_drawing = False
3839
self._bbox_queue = []
3940
self._drawRect = None
4041

@@ -124,7 +125,14 @@ def draw(self):
124125
"""
125126
# The Agg draw is done here; delaying causes problems with code that
126127
# uses the result of the draw() to update plot elements.
127-
super(FigureCanvasQTAggBase, self).draw()
128+
if self._agg_is_drawing:
129+
return
130+
131+
self._agg_is_drawing = True
132+
try:
133+
super(FigureCanvasQTAggBase, self).draw()
134+
finally:
135+
self._agg_is_drawing = False
128136
self.update()
129137

130138
def draw_idle(self):
@@ -135,7 +143,7 @@ def draw_idle(self):
135143
# current event loop in order to ensure thread affinity and to
136144
# accumulate multiple draw requests from event handling.
137145
# TODO: queued signal connection might be safer than singleShot
138-
if not self._agg_draw_pending:
146+
if not (self._agg_draw_pending or self._agg_is_drawing):
139147
self._agg_draw_pending = True
140148
QtCore.QTimer.singleShot(0, self.__draw_idle_agg)
141149

@@ -146,6 +154,7 @@ def __draw_idle_agg(self, *args):
146154
# we have now tried this function at least once, do not run
147155
# again until re-armed. Doing this here rather than after
148156
# protects against recursive calls triggered through self.draw
157+
# The recursive call is via `repaintEvent`
149158
self._agg_draw_pending = False
150159
# if negative size, bail
151160
if self.height() < 0 or self.width() < 0:

0 commit comments

Comments
 (0)
0