Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Qt5: Add flag that informs paintEvent if the agg buffer needs to updated, fix rubberband #4962

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 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2763,6 +2763,10 @@ def draw_rubberband(self, event, x0, y0, x1, y1):
"""Draw a rectangle rubberband to indicate zoom limits"""
pass

def remove_rubberband(self):
"""Remove the rubberband"""
pass

def forward(self, *args):
"""Move forward in the view lim stack"""
self._views.forward()
Expand Down Expand Up @@ -3036,6 +3040,8 @@ def release_zoom(self, event):
self.canvas.mpl_disconnect(zoom_id)
self._ids_zoom = []

self.remove_rubberband()

if not self._xypress:
return

Expand Down
5 changes: 3 additions & 2 deletions lib/matplotlib/backends/backend_qt4agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def new_figure_manager_given_figure(num, figure):
return FigureManagerQT(canvas, num)


class FigureCanvasQTAgg(FigureCanvasQTAggBase,
FigureCanvasQT, FigureCanvasAgg):
class FigureCanvasQTAgg(FigureCanvasQT, FigureCanvasQTAggBase,
FigureCanvasAgg):
"""
The canvas the figure renders into. Calls the draw and print fig
methods, creates the renderers, etc...
Expand All @@ -69,6 +69,7 @@ def __init__(self, figure):
if DEBUG:
print('FigureCanvasQtAgg: ', figure)
FigureCanvasQT.__init__(self, figure)
FigureCanvasQTAggBase.__init__(self, figure)
FigureCanvasAgg.__init__(self, figure)
self._drawRect = None
self.blitbox = None
Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/backends/backend_qt5.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,6 @@ def stop_event_loop(self):

stop_event_loop.__doc__ = FigureCanvasBase.stop_event_loop_default.__doc__

def draw_idle(self):
self.update()


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably stay, do we want to fallback to the base implementation of draw_idle?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not really clear to me what's the idea of the split between qt5 and qt5agg. Draw is defined in qt5agg, draw_idle is defined in qt5. It seems reasonable to have both at the same spot where the whole draw mechanism is implemented. Its not gone, it just moved from qt5 to qt5agg.

class MainWindow(QtWidgets.QMainWindow):
closing = QtCore.Signal()
Expand Down Expand Up @@ -685,6 +682,9 @@ def draw_rubberband(self, event, x0, y0, x1, y1):
rect = [int(val)for val in (min(x0, x1), min(y0, y1), w, h)]
self.canvas.drawRectangle(rect)

def remove_rubberband(self):
self.canvas.drawRectangle(None)

def configure_subplots(self):
image = os.path.join(matplotlib.rcParams['datapath'],
'images', 'matplotlib.png')
Expand Down
34 changes: 25 additions & 9 deletions lib/matplotlib/backends/backend_qt5agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,26 @@ class FigureCanvasQTAggBase(object):

Public attribute

figure - A Figure instance
"""
figure - A Figure instance
"""

def __init__(self, figure):
super(FigureCanvasQTAggBase, self).__init__(figure=figure)
self._agg_redraw_flag = True

def drawRectangle(self, rect):
self._drawRect = rect
self.draw_idle()
self.update()

def paintEvent(self, e):
"""
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.
"""
FigureCanvasAgg.draw(self)
if self._agg_redraw_flag:
self._agg_redraw_flag = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please flip the order on these lines so it is only cleared after the Agg draw has succeeded with out exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have, but I'm still confused about these draw_idle callbacks from within the draw call. If there is a reason for those you cannot clear the flag after draw since it might have been re-set during draw on purpose.

FigureCanvasAgg.draw(self)

# FigureCanvasQT.paintEvent(self, e)
if DEBUG:
Expand Down Expand Up @@ -134,9 +140,14 @@ def paintEvent(self, e):
pixmap = QtGui.QPixmap.fromImage(qImage)
p = QtGui.QPainter(self)
p.drawPixmap(QtCore.QPoint(l, self.renderer.height-t), pixmap)

# draw the zoom rectangle to the QPainter
if self._drawRect is not None:
p.setPen(QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.DotLine))
x, y, w, h = self._drawRect
p.drawRect(x, y, w, h)
p.end()
self.blitbox = None
self._drawRect = None

def draw(self):
"""
Expand All @@ -147,6 +158,11 @@ def draw(self):
# causes problems with code that uses the result of the
# draw() to update plot elements.
FigureCanvasAgg.draw(self)
self._agg_redraw_flag = False
self.update()

def draw_idle(self):
self._agg_redraw_flag = True
self.update()

def blit(self, bbox=None):
Expand All @@ -161,15 +177,16 @@ def blit(self, bbox=None):
self.blitbox = bbox
l, b, w, h = bbox.bounds
t = b + h
self._agg_redraw_flag = False # don't repaint the agg buffer in blit()
self.repaint(l, self.renderer.height-t, w, h)

def print_figure(self, *args, **kwargs):
FigureCanvasAgg.print_figure(self, *args, **kwargs)
self.draw()


class FigureCanvasQTAgg(FigureCanvasQTAggBase,
FigureCanvasQT, FigureCanvasAgg):
class FigureCanvasQTAgg(FigureCanvasQT, FigureCanvasQTAggBase,
FigureCanvasAgg):
"""
The canvas the figure renders into. Calls the draw and print fig
methods, creates the renderers, etc.
Expand All @@ -184,8 +201,7 @@ class FigureCanvasQTAgg(FigureCanvasQTAggBase,
def __init__(self, figure):
if DEBUG:
print('FigureCanvasQtAgg: ', figure)
FigureCanvasQT.__init__(self, figure)
FigureCanvasAgg.__init__(self, figure)
super(FigureCanvasQTAgg, self).__init__(figure=figure)
self._drawRect = None
self.blitbox = None
self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
Expand Down