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

Skip to content

Commit 30f8b77

Browse files
first implementation of Toolmanager for the Wx backends
1 parent 0984694 commit 30f8b77

File tree

2 files changed

+147
-10
lines changed

2 files changed

+147
-10
lines changed

examples/user_interfaces/toolmanager_sgskip.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
matplotlib.use('GTK3Cairo')
2020
# matplotlib.use('TkAgg')
2121
# matplotlib.use('QT5Agg')
22+
# matplotlib.use('WxAgg')
2223
matplotlib.rcParams['toolbar'] = 'toolmanager'
2324
import matplotlib.pyplot as plt
2425
from matplotlib.backend_tools import ToolBase, ToolToggleBase

lib/matplotlib/backends/backend_wx.py

Lines changed: 146 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
import matplotlib
1919
from matplotlib.backend_bases import (
2020
_Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
21-
NavigationToolbar2, RendererBase, TimerBase, cursors)
21+
NavigationToolbar2, RendererBase, TimerBase, cursors, ToolContainerBase,
22+
StatusbarBase)
2223
from matplotlib.backend_bases import _has_pil
2324

2425
from matplotlib._pylab_helpers import Gcf
@@ -27,6 +28,7 @@
2728
from matplotlib.path import Path
2829
from matplotlib.transforms import Affine2D
2930
from matplotlib.widgets import SubplotTool
31+
from matplotlib.backend_managers import ToolManager
3032
from matplotlib import cbook, rcParams, backend_tools
3133

3234
import wx
@@ -1158,9 +1160,8 @@ def __init__(self, num, fig):
11581160
# Frame will be sized later by the Fit method
11591161
DEBUG_MSG("__init__()", 1, self)
11601162
self.num = num
1163+
_set_frame_icon(self)
11611164

1162-
statbar = StatusBarWx(self)
1163-
self.SetStatusBar(statbar)
11641165
self.canvas = self.get_canvas(fig)
11651166
self.canvas.SetInitialSize(wx.Size(fig.bbox.width, fig.bbox.height))
11661167
self.canvas.SetFocus()
@@ -1169,7 +1170,18 @@ def __init__(self, num, fig):
11691170
# By adding toolbar in sizer, we are able to put it at the bottom
11701171
# of the frame - so appearance is closer to GTK version
11711172

1172-
self.toolbar = self._get_toolbar(statbar)
1173+
self.toolmanager = self._get_toolmanager()
1174+
if self.toolmanager:
1175+
self.statusbar = StatusbarWx(self, self.toolmanager)
1176+
else:
1177+
self.statusbar = StatusBarWx(self)
1178+
self.SetStatusBar(self.statusbar)
1179+
self.toolbar = self._get_toolbar(self.statusbar)
1180+
1181+
if self.toolmanager:
1182+
backend_tools.add_tools_to_manager(self.toolmanager)
1183+
if self.toolbar:
1184+
backend_tools.add_tools_to_container(self.toolbar)
11731185

11741186
if self.toolbar is not None:
11751187
self.toolbar.Realize()
@@ -1203,10 +1215,19 @@ def _get_toolbar(self, statbar):
12031215
if rcParams['toolbar'] == 'toolbar2':
12041216
toolbar = NavigationToolbar2Wx(self.canvas)
12051217
toolbar.set_status_bar(statbar)
1218+
elif matplotlib.rcParams['toolbar'] == 'toolmanager':
1219+
toolbar = ToolbarWx(self.toolmanager, self)
12061220
else:
12071221
toolbar = None
12081222
return toolbar
12091223

1224+
def _get_toolmanager(self):
1225+
if matplotlib.rcParams['toolbar'] == 'toolmanager':
1226+
toolmanager = ToolManager(self.canvas.figure)
1227+
else:
1228+
toolmanager = None
1229+
return toolmanager
1230+
12101231
def get_canvas(self, fig):
12111232
return FigureCanvasWx(self, -1, fig)
12121233

@@ -1263,8 +1284,8 @@ def __init__(self, canvas, num, frame):
12631284
self.frame = frame
12641285
self.window = frame
12651286

1266-
self.tb = frame.GetToolBar()
1267-
self.toolbar = self.tb # consistent with other backends
1287+
self.toolmanager = frame.toolmanager
1288+
self.toolbar = frame.GetToolBar()
12681289

12691290
def show(self):
12701291
self.frame.Show()
@@ -1328,6 +1349,22 @@ def _load_bitmap(filename):
13281349
return bmp
13291350

13301351

1352+
_FRAME_ICON = None
1353+
def _set_frame_icon(frame):
1354+
# set frame icon
1355+
global _FRAME_ICON
1356+
if not _FRAME_ICON:
1357+
_FRAME_ICON = bundle = wx.IconBundle()
1358+
for image in ('matplotlib.png', 'matplotlib_large.png'):
1359+
image = os.path.join(matplotlib.rcParams['datapath'], 'images',
1360+
image)
1361+
if not os.path.exists(image): continue
1362+
icon = wx.Icon(_load_bitmap(image))
1363+
if not icon.IsOk(): return
1364+
bundle.AddIcon(icon)
1365+
frame.SetIcons(_FRAME_ICON)
1366+
1367+
13311368
class MenuButtonWx(wx.Button):
13321369
"""
13331370
wxPython does not permit a menu to be incorporated directly into a toolbar.
@@ -1675,7 +1712,7 @@ class StatusBarWx(wx.StatusBar):
16751712
convenience.
16761713
"""
16771714

1678-
def __init__(self, parent):
1715+
def __init__(self, parent, *args, **kwargs):
16791716
wx.StatusBar.__init__(self, parent, -1)
16801717
self.SetFieldsCount(2)
16811718
self.SetStatusText("None", 1)
@@ -1690,9 +1727,107 @@ def set_function(self, string):
16901727

16911728

16921729
# tools for matplotlib.backend_managers.ToolManager:
1693-
# for now only SaveFigure, SetCursor and Rubberband are implemented
1694-
# once a ToolbarWx is implemented, also FigureManagerWx needs to be
1695-
# modified, similar to pull request #9934
1730+
1731+
class ToolbarWx(ToolContainerBase, wx.ToolBar):
1732+
def __init__(self, toolmanager, parent, style=wx.TB_HORIZONTAL):
1733+
ToolContainerBase.__init__(self, toolmanager)
1734+
wx.ToolBar.__init__(self, parent, -1, style=style)
1735+
self._toolitems = {}
1736+
self._groups = {}
1737+
self._last = None
1738+
1739+
def add_toolitem(
1740+
self, name, group, position, image_file, description, toggle):
1741+
1742+
before, group = self._add_to_group(group, name, position)
1743+
idx = self.GetToolPos(before.Id)
1744+
if image_file:
1745+
bmp = _load_bitmap(image_file)
1746+
kind = wx.ITEM_NORMAL if not toggle else wx.ITEM_CHECK
1747+
tool = self.InsertTool(idx, -1, name, bmp, wx.NullBitmap, kind,
1748+
description or "")
1749+
else:
1750+
size = (self.GetTextExtent(name)[0]+10,-1)
1751+
if toggle:
1752+
control = wx.ToggleButton(self, -1, name, size=size)
1753+
else:
1754+
control = wx.Button(self, -1, name, size=size)
1755+
tool = self.InsertControl(idx, control, label=name)
1756+
self.Realize()
1757+
1758+
def handler(event):
1759+
self.trigger_tool(name)
1760+
1761+
if image_file:
1762+
self.Bind(wx.EVT_TOOL, handler, tool)
1763+
else:
1764+
control.Bind(wx.EVT_LEFT_DOWN, handler)
1765+
1766+
self._last = tool
1767+
self._toolitems.setdefault(name, [])
1768+
group.insert(position, tool)
1769+
self._toolitems[name].append((tool, handler))
1770+
1771+
def _add_to_group(self, group, name, position):
1772+
gr = self._groups.get(group, [])
1773+
if not gr:
1774+
sep = self.AddSeparator()
1775+
gr.append(sep)
1776+
before = gr[position]
1777+
self._groups[group] = gr
1778+
return before, gr
1779+
1780+
def toggle_toolitem(self, name, toggled):
1781+
if name not in self._toolitems:
1782+
return
1783+
for tool, handler in self._toolitems[name]:
1784+
if not tool.IsControl():
1785+
self.ToggleTool(tool.Id, toggled)
1786+
else:
1787+
tool.GetControl().SetValue(toggled)
1788+
self.Refresh()
1789+
def remove_toolitem(self, name):
1790+
for tool, handler in self._toolitems[name]:
1791+
self.DeleteTool(tool.Id)
1792+
del self._toolitems[name]
1793+
1794+
1795+
class StatusbarWx(StatusbarBase, wx.StatusBar):
1796+
"""for use with ToolManager"""
1797+
def __init__(self, parent, *args, **kwargs):
1798+
StatusbarBase.__init__(self, *args, **kwargs)
1799+
wx.StatusBar.__init__(self, parent, -1)
1800+
self.SetFieldsCount(1)
1801+
self.SetStatusText("")
1802+
1803+
def set_message(self, s):
1804+
self.SetStatusText(s)
1805+
1806+
1807+
class ConfigureSubplotsWx(backend_tools.ConfigureSubplotsBase):
1808+
def trigger(self, *args):
1809+
self.configure_subplots()
1810+
1811+
def configure_subplots(self):
1812+
frame = wx.Frame(None, -1, "Configure subplots")
1813+
_set_frame_icon(frame)
1814+
frame.toolmanager = None
1815+
1816+
toolfig = Figure((6, 3))
1817+
canvas = self.get_canvas(frame, toolfig)
1818+
1819+
# Now put all into a sizer
1820+
sizer = wx.BoxSizer(wx.VERTICAL)
1821+
# This way of adding to sizer allows resizing
1822+
sizer.Add(canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
1823+
frame.SetSizer(sizer)
1824+
frame.Fit()
1825+
tool = SubplotTool(self.canvas.figure, toolfig)
1826+
frame.Show()
1827+
1828+
def get_canvas(self, frame, fig):
1829+
return type(self.canvas)(frame, -1, fig)
1830+
16961831

16971832
class SaveFigureWx(backend_tools.SaveFigureBase):
16981833
def trigger(self, *args):
@@ -1827,6 +1962,7 @@ def remove_rubberband(self, dc=None):
18271962

18281963

18291964
backend_tools.ToolSaveFigure = SaveFigureWx
1965+
backend_tools.ToolConfigureSubplots = ConfigureSubplotsWx
18301966
backend_tools.ToolSetCursor = SetCursorWx
18311967
backend_tools.ToolRubberband = RubberbandWx
18321968

0 commit comments

Comments
 (0)