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

Skip to content

Deprecate NavigationToolbar2._init_toolbar. #17111

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

Merged
merged 1 commit into from
Apr 30, 2020
Merged
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
10 changes: 10 additions & 0 deletions doc/api/api_changes_3.3/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,16 @@ The ``Fil``, ``Fill``, ``Filll``, ``NegFil``, ``NegFill``, ``NegFilll``, and
``SsGlue`` classes in the :mod:`matplotlib.mathtext` module are deprecated.
As an alternative, directly construct glue instances with ``Glue("fil")``, etc.

NavigationToolbar2._init_toolbar
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Overriding this method to initialize third-party toolbars is deprecated.
Instead, the toolbar should be initialized in the ``__init__`` method of the
subclass (which should call the base-class' ``__init__`` as appropriate). To
keep back-compatibility with earlier versions of Matplotlib (which *required*
``_init_toolbar`` to be overridden), a fully empty implementation (``def
_init_toolbar(self): pass``) may be kept and will not trigger the deprecation
warning.

NavigationToolbar2QT.parent and .basedir
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These attributes are deprecated. In order to access the parent window, use
Expand Down
26 changes: 19 additions & 7 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2668,11 +2668,11 @@ def __str__(self):

class NavigationToolbar2:
"""
Base class for the navigation cursor, version 2
Base class for the navigation cursor, version 2.

backends must implement a canvas that handles connections for
Backends must implement a canvas that handles connections for
'button_press_event' and 'button_release_event'. See
:meth:`FigureCanvasBase.mpl_connect` for more information
:meth:`FigureCanvasBase.mpl_connect` for more information.

They must also define

Expand All @@ -2682,9 +2682,6 @@ class NavigationToolbar2:
:meth:`set_cursor`
if you want the pointer icon to change

:meth:`_init_toolbar`
create your toolbar widget

:meth:`draw_rubberband` (optional)
draw the zoom to rect "rubberband" rectangle

Expand All @@ -2695,6 +2692,12 @@ class NavigationToolbar2:
you can change the history back / forward buttons to
indicate disabled / enabled state.

and override ``__init__`` to set up the toolbar -- without forgetting to
call the base-class init. Typically, ``__init__`` needs to set up toolbar
buttons connected to the `home`, `back`, `forward`, `pan`, `zoom`, and
`save_figure` methods and using standard icons in the "images" subdirectory
of the data path.

That's it, we'll do the rest!
"""

Expand Down Expand Up @@ -2724,7 +2727,15 @@ def __init__(self, canvas):
self._xypress = None # location and axis info at the time of the press
# This cursor will be set after the initial draw.
self._lastCursor = cursors.POINTER
self._init_toolbar()

init = cbook._deprecate_method_override(
__class__._init_toolbar, self, allow_empty=True, since="3.3",
addendum="Please fully initialize the toolbar in your subclass' "
"__init__; a fully empty _init_toolbar implementation may be kept "
"for compatibility with earlier versions of Matplotlib.")
if init:
init()

self._id_press = self.canvas.mpl_connect(
'button_press_event', self._zoom_pan_handler)
self._id_release = self.canvas.mpl_connect(
Expand Down Expand Up @@ -2787,6 +2798,7 @@ def home(self, *args):
self.set_history_buttons()
self._update_view()

@cbook.deprecated("3.3", alternative="__init__")
def _init_toolbar(self):
"""
This is where you actually build the GUI widgets (called by
Expand Down
68 changes: 23 additions & 45 deletions lib/matplotlib/backends/_backend_tk.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,29 @@ def __init__(self, canvas, window, *, pack_toolbar=True):
# Avoid using self.window (prefer self.canvas.get_tk_widget().master),
# so that Tool implementations can reuse the methods.
self.window = window

tk.Frame.__init__(self, master=window, borderwidth=2,
width=int(canvas.figure.bbox.width), height=50)

self._buttons = {}
for text, tooltip_text, image_file, callback in self.toolitems:
if text is None:
# Add a spacer; return value is unused.
self._Spacer()
else:
self._buttons[text] = button = self._Button(
text,
str(cbook._get_data_path(f"images/{image_file}.gif")),
toggle=callback in ["zoom", "pan"],
command=getattr(self, callback),
)
if tooltip_text is not None:
ToolTip.createToolTip(button, tooltip_text)

self.message = tk.StringVar(master=self)
self._message_label = tk.Label(master=self, textvariable=self.message)
self._message_label.pack(side=tk.RIGHT)

NavigationToolbar2.__init__(self, canvas)
if pack_toolbar:
self.pack(side=tk.BOTTOM, fill=tk.X)
Expand Down Expand Up @@ -547,51 +570,6 @@ def _Spacer(self):
s.pack(side=tk.LEFT, padx=5)
return s

def _init_toolbar(self):
xmin, xmax = self.canvas.figure.bbox.intervalx
height, width = 50, xmax-xmin
tk.Frame.__init__(self, master=self.window,
width=int(width), height=int(height),
borderwidth=2)

self.update() # Make axes menu

self._buttons = {}
for text, tooltip_text, image_file, callback in self.toolitems:
if text is None:
# Add a spacer; return value is unused.
self._Spacer()
else:
self._buttons[text] = button = self._Button(
text,
str(cbook._get_data_path(f"images/{image_file}.gif")),
toggle=callback in ["zoom", "pan"],
command=getattr(self, callback),
)
if tooltip_text is not None:
ToolTip.createToolTip(button, tooltip_text)

self.message = tk.StringVar(master=self)
self._message_label = tk.Label(master=self, textvariable=self.message)
self._message_label.pack(side=tk.RIGHT)

def _update_buttons_checked(self):
for name, mode in [("Pan", "PAN"), ("Zoom", "ZOOM")]:
button = self._buttons.get(name)
if button:
if self.mode.name == mode and not button.var.get():
button.select()
elif self.mode.name != mode and button.var.get():
button.deselect()

def pan(self, *args):
super().pan(*args)
self._update_buttons_checked()

def zoom(self, *args):
super().zoom(*args)
self._update_buttons_checked()

def configure_subplots(self):
toolfig = Figure(figsize=(6, 3))
window = tk.Toplevel()
Expand Down
72 changes: 36 additions & 36 deletions lib/matplotlib/backends/backend_gtk3.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,43 +451,7 @@ class NavigationToolbar2GTK3(NavigationToolbar2, Gtk.Toolbar):
def __init__(self, canvas, window):
self.win = window
GObject.GObject.__init__(self)
NavigationToolbar2.__init__(self, canvas)

@cbook.deprecated("3.3")
@property
def ctx(self):
return self.canvas.get_property("window").cairo_create()

def set_message(self, s):
self.message.set_label(s)

def set_cursor(self, cursor):
self.canvas.get_property("window").set_cursor(cursord[cursor])
Gtk.main_iteration()

def draw_rubberband(self, event, x0, y0, x1, y1):
# adapted from
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744
ctx = self.canvas.get_property("window").cairo_create()

# todo: instead of redrawing the entire figure, copy the part of
# the figure that was covered by the previous rubberband rectangle
self.canvas.draw()

height = self.canvas.figure.bbox.height
y1 = height - y1
y0 = height - y0
w = abs(x1 - x0)
h = abs(y1 - y0)
rect = [int(val) for val in (min(x0, x1), min(y0, y1), w, h)]

ctx.new_path()
ctx.set_line_width(0.5)
ctx.rectangle(*rect)
ctx.set_source_rgb(0, 0, 0)
ctx.stroke()

def _init_toolbar(self):
self.set_style(Gtk.ToolbarStyle.ICONS)

self._gtk_ids = {}
Expand Down Expand Up @@ -521,6 +485,42 @@ def _init_toolbar(self):

self.show_all()

NavigationToolbar2.__init__(self, canvas)

@cbook.deprecated("3.3")
@property
def ctx(self):
return self.canvas.get_property("window").cairo_create()

def set_message(self, s):
self.message.set_label(s)

def set_cursor(self, cursor):
self.canvas.get_property("window").set_cursor(cursord[cursor])
Gtk.main_iteration()

def draw_rubberband(self, event, x0, y0, x1, y1):
# adapted from
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744
self.ctx = self.canvas.get_property("window").cairo_create()

# todo: instead of redrawing the entire figure, copy the part of
# the figure that was covered by the previous rubberband rectangle
self.canvas.draw()

height = self.canvas.figure.bbox.height
y1 = height - y1
y0 = height - y0
w = abs(x1 - x0)
h = abs(y1 - y0)
rect = [int(val) for val in (min(x0, x1), min(y0, y1), w, h)]

self.ctx.new_path()
self.ctx.set_line_width(0.5)
self.ctx.rectangle(rect[0], rect[1], rect[2], rect[3])
self.ctx.set_source_rgb(0, 0, 0)
self.ctx.stroke()

def _update_buttons_checked(self):
for name, active in [("Pan", "PAN"), ("Zoom", "ZOOM")]:
button = self._gtk_ids.get(name)
Expand Down
5 changes: 2 additions & 3 deletions lib/matplotlib/backends/backend_macosx.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ def close(self):
class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):

def __init__(self, canvas):
NavigationToolbar2.__init__(self, canvas)

def _init_toolbar(self):
self.canvas = canvas # Needed by the _macosx __init__.
_macosx.NavigationToolbar2.__init__(
self, str(cbook._get_data_path('images')))
NavigationToolbar2.__init__(self, canvas)

def draw_rubberband(self, event, x0, y0, x1, y1):
self.canvas.set_rubberband(int(x0), int(y0), int(x1), int(y1))
Expand Down
53 changes: 27 additions & 26 deletions lib/matplotlib/backends/backend_qt5.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,36 +639,12 @@ class NavigationToolbar2QT(NavigationToolbar2, QtWidgets.QToolBar):

def __init__(self, canvas, parent, coordinates=True):
"""coordinates: should we show the coordinates on the right?"""
QtWidgets.QToolBar.__init__(self, parent)

self._parent = parent
self.coordinates = coordinates
self._actions = {} # mapping of toolitem method names to QActions.
QtWidgets.QToolBar.__init__(self, parent)
NavigationToolbar2.__init__(self, canvas)

@cbook.deprecated("3.3", alternative="self.canvas.parent()")
@property
def parent(self):
return self._parent

@cbook.deprecated(
"3.3", alternative="os.path.join(mpl.get_data_path(), 'images')")
@property
def basedir(self):
return str(cbook._get_data_path('images'))

def _icon(self, name, color=None):
if is_pyqt5():
name = name.replace('.png', '_large.png')
pm = QtGui.QPixmap(str(cbook._get_data_path('images', name)))
qt_compat._setDevicePixelRatio(pm, self.canvas._dpi_ratio)
if color is not None:
mask = pm.createMaskFromColor(QtGui.QColor('black'),
QtCore.Qt.MaskOutColor)
pm.fill(color)
pm.setMask(mask)
return QtGui.QIcon(pm)

def _init_toolbar(self):
background_color = self.palette().color(self.backgroundRole())
foreground_color = self.palette().color(self.foregroundRole())
icon_color = (foreground_color
Expand Down Expand Up @@ -699,6 +675,31 @@ def _init_toolbar(self):
labelAction = self.addWidget(self.locLabel)
labelAction.setVisible(True)

NavigationToolbar2.__init__(self, canvas)

@cbook.deprecated("3.3", alternative="self.canvas.parent()")
@property
def parent(self):
return self._parent

@cbook.deprecated(
"3.3", alternative="os.path.join(mpl.get_data_path(), 'images')")
@property
def basedir(self):
return str(cbook._get_data_path('images'))

def _icon(self, name, color=None):
if is_pyqt5():
name = name.replace('.png', '_large.png')
pm = QtGui.QPixmap(str(cbook._get_data_path('images', name)))
qt_compat._setDevicePixelRatio(pm, qt_compat._devicePixelRatio(self))
if color is not None:
mask = pm.createMaskFromColor(QtGui.QColor('black'),
QtCore.Qt.MaskOutColor)
pm.fill(color)
pm.setMask(mask)
return QtGui.QIcon(pm)

def edit_parameters(self):
axes = self.canvas.figure.get_axes()
if not axes:
Expand Down
3 changes: 2 additions & 1 deletion lib/matplotlib/backends/backend_webagg_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,10 @@ class NavigationToolbar2WebAgg(backend_bases.NavigationToolbar2):
if name_of_method in _ALLOWED_TOOL_ITEMS
]

def _init_toolbar(self):
def __init__(self, canvas):
self.message = ''
self.cursor = 0
super().__init__(canvas)

def set_message(self, message):
if message != self.message:
Expand Down
28 changes: 12 additions & 16 deletions lib/matplotlib/backends/backend_wx.py
Original file line number Diff line number Diff line change
Expand Up @@ -1104,22 +1104,6 @@ def _set_frame_icon(frame):
class NavigationToolbar2Wx(NavigationToolbar2, wx.ToolBar):
def __init__(self, canvas):
wx.ToolBar.__init__(self, canvas.GetParent(), -1)
NavigationToolbar2.__init__(self, canvas)
self._idle = True
self.prevZoomRect = None
# for now, use alternate zoom-rectangle drawing on all
# Macs. N.B. In future versions of wx it may be possible to
# detect Retina displays with window.GetContentScaleFactor()
# and/or dc.GetContentScaleFactor()
self.retinaFix = 'wxMac' in wx.PlatformInfo

def get_canvas(self, frame, fig):
return type(self.canvas)(frame, -1, fig)

def _init_toolbar(self):
_log.debug("%s - _init_toolbar", type(self))

self._parent = self.canvas.GetParent()

self.wx_ids = {}
for text, tooltip_text, image_file, callback in self.toolitems:
Expand All @@ -1140,6 +1124,18 @@ def _init_toolbar(self):

self.Realize()

NavigationToolbar2.__init__(self, canvas)
self._idle = True
self.prevZoomRect = None
# for now, use alternate zoom-rectangle drawing on all
# Macs. N.B. In future versions of wx it may be possible to
# detect Retina displays with window.GetContentScaleFactor()
# and/or dc.GetContentScaleFactor()
self.retinaFix = 'wxMac' in wx.PlatformInfo

def get_canvas(self, frame, fig):
return type(self.canvas)(frame, -1, fig)

def zoom(self, *args):
self.ToggleTool(self.wx_ids['Pan'], False)
NavigationToolbar2.zoom(self, *args)
Expand Down
Loading