10000 Merge pull request #22250 from anntzer/get_toolbar · matplotlib/matplotlib@80073f6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 80073f6

Browse files
authored
Merge pull request #22250 from anntzer/get_toolbar
Unify toolbar init across backends.
2 parents 355f7fa + a8108ac commit 80073f6

10 files changed

+58
-135
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2716,6 +2716,9 @@ class FigureManagerBase:
27162716
figure.canvas.manager.button_press_handler_id)
27172717
"""
27182718

2719+
_toolbar2_class = None
2720+
_toolmanager_toolbar_class = None
2721+
27192722
def __init__(self, canvas, num):
27202723
self.canvas = canvas
27212724
canvas.manager = self # store a pointer to parent
@@ -2733,7 +2736,19 @@ def __init__(self, canvas, num):
27332736
self.toolmanager = (ToolManager(canvas.figure)
27342737
if mpl.rcParams['toolbar'] == 'toolmanager'
27352738
else None)
2736-
self.toolbar = None
2739+
if (mpl.rcParams["toolbar"] == "toolbar2"
2740+
and self._toolbar2_class):
2741+
self.toolbar = self._toolbar2_class(self.canvas)
2742+
elif (mpl.rcParams["toolbar"] == "toolmanager"
2743+
and self._toolmanager_toolbar_class):
2744+
self.toolbar = self._toolmanager_toolbar_class(self.toolmanager)
2745+
else:
2746+
self.toolbar = None
2747+
2748+
if self.toolmanager:
2749+
tools.add_tools_to_manager(self.toolmanager)
2750+
if self.toolbar:
2751+
tools.add_tools_to_container(self.toolbar)
27372752

27382753
@self.canvas.figure.add_axobserver
27392754
def notify_axes_change(fig):

lib/matplotlib/backends/_backend_tk.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -423,14 +423,8 @@ def __init__(self, canvas, num, window):
423423
self.window.withdraw()
424424
# packing toolbar first, because if space is getting low, last packed
425425
# widget is getting shrunk first (-> the canvas)
426-
self.toolbar = self._get_toolbar()
427426
self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
428427

429-
if self.toolmanager:
430-
backend_tools.add_tools_to_manager(self.toolmanager)
431-
if self.toolbar:
432-
backend_tools.add_tools_to_container(self.toolbar)
433-
434428
# If the window has per-monitor DPI awareness, then setup a Tk variable
435429
# to store the DPI, which will be updated by the C code, and the trace
436430
# will handle it on the Python side.
@@ -443,15 +437,6 @@ def __init__(self, canvas, num, window):
443437

444438
self._shown = False
445439

446-
def _get_toolbar(self):
447-
if mpl.rcParams['toolbar'] == 'toolbar2':
448-
toolbar = NavigationToolbar2Tk(self.canvas)
449-
elif mpl.rcParams['toolbar'] == 'toolmanager':
450-
toolbar = ToolbarTk(self.toolmanager)
451-
else:
452-
toolbar = None
453-
return toolbar
454-
455440
def _update_window_dpi(self, *args):
456441
newdpi = self._window_dpi.get()
457442
self.window.call('tk', 'scaling', newdpi / 72)
@@ -917,6 +902,8 @@ def trigger(self, *args):
917902

918903

919904
Toolbar = ToolbarTk
905+
FigureManagerTk._toolbar2_class = NavigationToolbar2Tk
906+
FigureManagerTk._toolmanager_toolbar_class = ToolbarTk
920907

921908

922909
@_Backend.export

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,6 @@ def __init__(self, canvas, num):
331331
# calculate size for window
332332
w, h = self.canvas.get_width_height()
333333

334-
self.toolbar = self._get_toolbar()
335-
336-
if self.toolmanager:
337-
backend_tools.add_tools_to_manager(self.toolmanager)
338-
if self.toolbar:
339-
backend_tools.add_tools_to_container(self.toolbar)
340-
341334
if self.toolbar is not None:
342335
self.toolbar.show()
343336
self.vbox.pack_end(self.toolbar, False, False, 0)
@@ -737,6 +730,8 @@ def error_msg_gtk(msg, parent=None):
737730
FigureCanvasGTK3, _backend_gtk.ConfigureSubplotsGTK)
738731
backend_tools._register_tool_class(
739732
FigureCanvasGTK3, _backend_gtk.RubberbandGTK)
733+
FigureManagerGTK3._toolbar2_class = NavigationToolbar2GTK3
734+
FigureManagerGTK3._toolmanager_toolbar_class = ToolbarGTK3
740735

741736

742737
@_BackendGTK.export

lib/matplotlib/backends/backend_gtk4.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,6 @@ def __init__(self, canvas, num):
279279
# calculate size for window
280280
w, h = self.canvas.get_width_height()
281281

282-
self.toolbar = self._get_toolbar()
283-
284-
if self.toolmanager:
285-
backend_tools.add_tools_to_manager(self.toolmanager)
286-
if self.toolbar:
287-
backend_tools.add_tools_to_container(self.toolbar)
288-
289282
if self.toolbar is not None:
290283
sw = Gtk.ScrolledWindow(vscrollbar_policy=Gtk.PolicyType.NEVER)
291284
sw.set_child(self.toolbar)
@@ -335,17 +328,6 @@ def full_screen_toggle(self):
335328
else:
336329
self.window.unfullscreen()
337330

338-
def _get_toolbar(self):
339-
# must be inited after the window, drawingArea and figure
340-
# attrs are set
341-
if mpl.rcParams['toolbar'] == 'toolbar2':
342-
toolbar = NavigationToolbar2GTK4(self.canvas)
343-
elif mpl.rcParams['toolbar'] == 'toolmanager':
344-
toolbar = ToolbarGTK4(self.toolmanager)
345-
else:
346-
toolbar = None
347-
return toolbar
348-
349331
def get_window_title(self):
350332
return self.window.get_title()
351333

@@ -673,6 +655,8 @@ def trigger(self, *args, **kwargs):
673655
backend_tools._register_tool_class(
674656
FigureCanvasGTK4, _backend_gtk.RubberbandGTK)
675657
Toolbar = ToolbarGTK4
658+
FigureManagerGTK4._toolbar2_class = NavigationToolbar2GTK4
659+
FigureManagerGTK4._toolmanager_toolbar_class = ToolbarGTK4
676660

677661

678662
@_BackendGTK.export

lib/matplotlib/backends/backend_macosx.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,30 +62,6 @@ def resize(self, width, height):
6262
self.draw_idle()
6363

6464

65-
class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
66-
"""
67-
Wrap everything up into a window for the pylab interface
68-
"""
69-
def __init__(self, canvas, num):
70-
_macosx.FigureManager.__init__(self, canvas)
71-
icon_path = str(cbook._get_data_path('images/matplotlib.pdf'))
72-
_macosx.FigureManager.set_icon(icon_path)
73-
FigureManagerBase.__init__(self, canvas, num)
74-
if mpl.rcParams['toolbar'] == 'toolbar2':
75-
self.toolbar = NavigationToolbar2Mac(canvas)
76-
else:
77-
self.toolbar = None
78-
if self.toolbar is not None:
79-
self.toolbar.update()
80-
81-
if mpl.is_interactive():
82-
self.show()
83-
self.canvas.draw_idle()
84-
85-
def close(self):
86-
Gcf.destroy(self)
87-
88-
8965
class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):
9066

9167
def __init__(self, canvas):
@@ -123,6 +99,24 @@ def set_message(self, message):
12399
_macosx.NavigationToolbar2.set_message(self, message.encode('utf-8'))
124100

125101

102+
class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
103+
_toolbar2_class = NavigationToolbar2Mac
104+
105+
def __init__(self, canvas, num):
106+
_macosx.FigureManager.__init__(self, canvas)
107+
icon_path = str(cbook._get_data_path('images/matplotlib.pdf'))
108+
_macosx.FigureManager.set_icon(icon_path)
109+
FigureManagerBase.__init__(self, canvas, num)
110+
if self.toolbar is not None:
111+
self.toolbar.update()
112+
if mpl.is_interactive():
113+
self.show()
114+
self.canvas.draw_idle()
115+
116+
def close(self):
117+
Gcf.destroy(self)
118+
119+
126120
@_Backend.export
127121
class _BackendMac(_Backend):
128122
FigureCanvas = FigureCanvasMac

lib/matplotlib/backends/backend_nbagg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class NavigationIPy(NavigationToolbar2WebAgg):
7272

7373

7474
class FigureManagerNbAgg(FigureManagerWebAgg):
75-
ToolbarCls = NavigationIPy
75+
_toolbar2_class = ToolbarCls = NavigationIPy
7676

7777
def __init__(self, canvas, num):
7878
self._shown = False

lib/matplotlib/backends/backend_qt.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,6 @@ def __init__(self, canvas, num):
529529

530530
self.window._destroying = False
531531

532-
self.toolbar = self._get_toolbar(self.canvas, self.window)
533-
534-
if self.toolmanager:
535-
backend_tools.add_tools_to_manager(self.toolmanager)
536-
if self.toolbar:
537-
backend_tools.add_tools_to_container(self.toolbar)
538-
539532
if self.toolbar:
540533
self.window.addToolBar(self.toolbar)
541534
tbs_height = self.toolbar.sizeHint().height()
@@ -582,17 +575,6 @@ def _widgetclosed(self):
582575
# Gcf can get destroyed before the Gcf.destroy
583576
# line is run, leading to a useless AttributeError.
584577

585-
10000 def _get_toolbar(self, canvas, parent):
586-
# must be inited after the window, drawingArea and figure
587-
# attrs are set
588-
if mpl.rcParams['toolbar'] == 'toolbar2':
589-
toolbar = NavigationToolbar2QT(canvas)
590-
elif mpl.rcParams['toolbar'] == 'toolmanager':
591-
toolbar = ToolbarQt(self.toolmanager)
592-
else:
593-
toolbar = None
594-
return toolbar
595-
596578
def resize(self, width, height):
597579
# The Qt methods return sizes in 'virtual' pixels so we do need to
598580
# rescale from physical to logical pixels.
@@ -1022,6 +1004,10 @@ def trigger(self, *args, **kwargs):
10221004
qApp.clipboard().setPixmap(pixmap)
10231005

10241006

1007+
FigureManagerQT._toolbar2_class = NavigationToolbar2QT
1008+
FigureManagerQT._toolmanager_toolbar_class = ToolbarQt
1009+
1010+
10251011
@_Backend.export
10261012
class _BackendQT(_Backend):
10271013
FigureCanvas = FigureCanvasQT

lib/matplotlib/backends/backend_webagg_core.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -453,20 +453,15 @@ def set_history_buttons(self):
453453

454454

455455
class FigureManagerWebAgg(backend_bases.FigureManagerBase):
456-
ToolbarCls = NavigationToolbar2WebAgg
456+
_toolbar2_class = ToolbarCls = NavigationToolbar2WebAgg
457457

458458
def __init__(self, canvas, num):
459459
self.web_sockets = set()
460460
super().__init__(canvas, num)
461-
self.toolbar = self._get_toolbar(canvas)
462461

463462
def show(self):
464463
pass
465464

466-
def _get_toolbar(self, canvas):
467-
toolbar = self.ToolbarCls(canvas)
468-
return toolbar
469-
470465
def resize(self, w, h, forward=True):
471466
self._send_event(
472467
'resize',

lib/matplotlib/backends/backend_wx.py

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -901,13 +901,9 @@ def __init__(self, num, fig, *, canvas_class=None):
901901

902902
self.figmgr = FigureManagerWx(self.canvas, num, self)
903903

904-
self.toolbar = self._get_toolbar()
905-
if self.figmgr.toolmanager:
906-
backend_tools.add_tools_to_manager(self.figmgr.toolmanager)
907-
if self.toolbar:
908-
backend_tools.add_tools_to_container(self.toolbar)
909-
if self.toolbar is not None:
910-
self.SetToolBar(self.toolbar)
904+
toolbar = self.canvas.manager.toolbar
905+
if toolbar is not None:
906+
self.SetToolBar(toolbar)
911907

912908
# On Windows, canvas sizing must occur after toolbar addition;
913909
# otherwise the toolbar further resizes the canvas.
@@ -920,18 +916,8 @@ def __init__(self, num, fig, *, canvas_class=None):
920916

921917
self.Bind(wx.EVT_CLOSE, self._on_close)
922918

923-
@property
924-
def toolmanager(self):
925-
return self.figmgr.toolmanager
926-
927-
def _get_toolbar(self):
928-
if mpl.rcParams['toolbar'] == 'toolbar2':
929-
toolbar = NavigationToolbar2Wx(self.canvas)
930-
elif mpl.rcParams['toolbar'] == 'toolmanager':
931-
toolbar = ToolbarWx(self.toolmanager)
932-
else:
933-
toolbar = None
934-
return toolbar
919+
toolmanager = property(lambda self: self.figmgr.toolmanager)
920+
toolbar = property(lambda self: self.GetToolBar()) # backcompat
935921

936922
@_api.deprecated(
937923
"3.6", alternative="the canvas_class constructor parameter")
@@ -956,7 +942,7 @@ def _on_close(self, event):
956942

957943
def Destroy(self, *args, **kwargs):
958944
try:
959-
self.canvas.mpl_disconnect(self.toolbar._id_drag)
945+
self.canvas.mpl_disconnect(self.canvas.manager.toolbar._id_drag)
960946
# Rationale for line above: see issue 2941338.
961947
except AttributeError:
962948
pass # classic toolbar lacks the attribute
@@ -965,8 +951,8 @@ def Destroy(self, *args, **kwargs):
965951
# MPLBACKEND=wxagg python -c 'from pylab import *; plot()'.
966952
if self and not self.IsBeingDeleted():
967953
super().Destroy(*args, **kwargs)
968-
# self.toolbar.Destroy() should not be necessary if the close event
969-
# is allowed to propagate.
954+
# toolbar.Destroy() should not be necessary if the close event is
955+
# allowed to propagate.
970956
return True
971957

972958

@@ -988,20 +974,7 @@ class FigureManagerWx(FigureManagerBase):
988974
def __init__(self, canvas, num, frame):
989975
_log.debug("%s - __init__()", type(self))
990976
self.frame = self.window = frame
991-
self._initializing = True
992977
super().__init__(canvas, num)
993-
self._initializing = False
994-
995-
@property
996-
def toolbar(self):
997-
return self.frame.GetToolBar()
998-
999-
@toolbar.setter
1000-
def toolbar(self, value):
1001-
# Never allow this, except that base class inits this to None before
1002-
# the frame is set up.
1003-
if not self._initializing:
1004-
raise AttributeError("can't set attribute")
1005978

1006979
def show(self):
1007980
# docstring inherited
@@ -1373,6 +1346,10 @@ def trigger(self, *args, **kwargs):
13731346
wx.TheClipboard.Close()
13741347

13751348

1349+
FigureManagerWx._toolbar2_class = NavigationToolbar2Wx
1350+
FigureManagerWx._toolmanager_toolbar_class = ToolbarWx
1351+
1352+
13761353
@_Backend.export
13771354
class _BackendWx(_Backend):
13781355
FigureCanvas = FigureCanvasWx

lib/matplotlib/tests/test_backend_bases.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
from matplotlib.backend_bases import (
55
FigureCanvasBase, LocationEvent, MouseButton, MouseEvent,
66
NavigationToolbar2, RendererBase)
7-
from matplotlib.backend_tools import (ToolZoom, ToolPan, RubberbandBase,
8-
ToolViewsPositions, _views_positions)
97
from matplotlib.figure import Figure
108
import matplotlib.pyplot as plt
119
import matplotlib.transforms as transforms
@@ -250,14 +248,6 @@ def test_toolbar_zoompan():
250248
plt.rcParams['toolbar'] = 'toolmanager'
251249
ax = plt.gca()
252250
assert ax.get_navigate_mode() is None
253-
ax.figure.canvas.manager.toolmanager.add_tool(name="zoom",
254-
tool=ToolZoom)
255-
ax.figure.canvas.manager.toolmanager.add_tool(name="pan",
256-
tool=ToolPan)
257-
ax.figure.canvas.manager.toolmanager.add_tool(name=_views_positions,
258-
tool=ToolViewsPositions)
259-
ax.figure.canvas.manager.toolmanager.add_tool(name='rubberband',
260-
tool=RubberbandBase)
261251
ax.figure.canvas.manager.toolmanager.trigger_tool('zoom')
262252
assert ax.get_navigate_mode() == "ZOOM"
263253
ax.figure.canvas.manager.toolmanager.trigger_tool('pan')

0 commit comments

Comments
 (0)
0