Python中如何重写Matplotlib工具栏的SAVE按钮功能?
问题:重写Matplotlib工具栏Save按钮功能失效
我尝试修改Matplotlib工具栏的Save按钮功能,希望点击按钮时先提示生成PDF报告,再执行默认的保存图表操作。参考论坛方案用toolbar.bind("save_figure", N_Save)绑定自定义函数,但完全无效。以下是完整代码:
import tkinter from matplotlib.backends.backend_tkagg import ( FigureCanvasTkAgg, NavigationToolbar2Tk) from matplotlib.backend_bases import key_press_handler from matplotlib.figure import Figure from matplotlib.backends.backend_wx import NavigationToolbar2 import numpy as np root = tkinter.Tk() root.wm_title("Embedding in Tk") fig = Figure(figsize=(5, 4), dpi=100) t = np.arange(0, 3, .01) fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t)) canvas = FigureCanvasTkAgg(fig, master=root) canvas.draw() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) toolbar = NavigationToolbar2Tk(canvas, root) toolbar.update() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) def N_Save(event): print("HELLOOOO") key_press_handler(event, canvas, toolbar) def on_key_press(event): print("you pressed {}".format(event.key)) key_press_handler(event, canvas, toolbar) canvas.mpl_connect("key_press_event", on_key_press) toolbar.bind("save_figure", N_Save) def _quit(): root.quit() root.destroy() button = tkinter.Button(master=root, text="Quit", command=_quit) button.pack(side=tkinter.BOTTOM) tkinter.mainloop()
原因分析
- 绑定方式错误:Tk后端的工具栏按钮并非通过
bind("save_figure")触发事件,而是每个按钮都有command属性,需要直接替换该属性才能覆盖原有功能。 - 导入冗余类:代码中导入了wx后端的
NavigationToolbar2,完全没用,属于无效导入。 - 错误调用保存逻辑:
key_press_handler是处理键盘事件的函数,不能用来触发保存操作,应该调用工具栏原生的save_figure方法。
解决方案
修改代码,找到工具栏中的Save按钮,替换其command为自定义函数,在函数中先执行PDF生成逻辑,再调用原生保存功能:
import tkinter from matplotlib.backends.backend_tkagg import ( FigureCanvasTkAgg, NavigationToolbar2Tk) from matplotlib.figure import Figure import numpy as np root = tkinter.Tk() root.wm_title("Embedding in Tk") fig = Figure(figsize=(5, 4), dpi=100) t = np.arange(0, 3, .01) fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t)) canvas = FigureCanvasTkAgg(fig, master=root) canvas.draw() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) toolbar = NavigationToolbar2Tk(canvas, root) toolbar.update() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) # 自定义保存函数 def custom_save(): # 这里添加生成PDF报告的逻辑,比如弹出提示或直接生成PDF print("生成PDF报告中...") # 调用工具栏原生的保存功能 toolbar.save_figure() # 找到Save按钮并替换其command for child in toolbar.winfo_children(): if isinstance(child, tkinter.Button) and child.cget("text") == "Save": child.config(command=custom_save) break def on_key_press(event): print("you pressed {}".format(event.key)) # 如果需要保留键盘快捷键触发的保存,也可以在这里调用自定义函数 if event.key == "ctrl+s": custom_save() canvas.mpl_connect("key_press_event", on_key_press) def _quit(): root.quit() root.destroy() button = tkinter.Button(master=root, text="Quit", command=_quit) button.pack(side=tkinter.BOTTOM) tkinter.mainloop()
关键修改点
- 移除了无用的
NavigationToolbar2导入和key_press_handler的错误调用。 - 通过遍历工具栏子组件找到Save按钮,替换其
command属性为自定义函数。 - 在自定义函数中先执行PDF生成逻辑,再调用
toolbar.save_figure()触发原生保存对话框。 - 可选:如果需要保留Ctrl+S快捷键的自定义逻辑,在键盘事件处理中判断按键并调用自定义函数。
内容的提问来源于stack exchange,提问作者Fabián Gabriel L.S.
相关产品推荐
相关产品推荐

