macOS下Matplotlib图表显示后应用图标无法恢复原状态
macOS下Tkinter+Matplotlib Dock图标无法恢复的解决方案
问题原因
macOS下Matplotlib的TkAgg后端会为图表创建独立的Tk根窗口,导致Dock栏的图标关联切换到这个新窗口;关闭图表后,系统不会自动把图标关联切回原Tk应用窗口,就出现了图标无法恢复的问题。
解决方案1:将图表嵌入Tkinter窗口(最稳妥)
直接把Matplotlib图表嵌入到Tkinter的窗口或框架中,不弹出独立的Matplotlib窗口,从根源避免图标切换问题。
修改后的完整代码:
from tkinter import * import matplotlib import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg root = Tk() def show_graph(): # 数据准备 a = [90.2, 123.8, 110.2, 108.1, 115.0] b = [100, 100, 100, 100, 100] target = [98, 98, 98, 98, 98] weeks = [0, 1, 2, 3, 4] # 创建图表 figure1 = plt.figure(figsize=(4, 2), dpi=200) ax = figure1.add_subplot(111) ax.set_xticks(weeks) # 修正原代码中xticks与数据不匹配的问题 ax.plot(weeks, a, '--.', label="A") ax.plot(b, 'r--', label="B") ax.plot(target, 'g--', label="C") ax.legend() ax.set_xlabel('Week') ax.set_ylabel('A', labelpad=1) ax.grid(True, which="both", ls="-") # 新建Tk子窗口并嵌入图表 graph_window = Toplevel(root) graph_window.title("Graph") canvas = FigureCanvasTkAgg(figure1, master=graph_window) canvas.draw() canvas.get_tk_widget().pack(padx=10, pady=10) if __name__ == '__main__': matplotlib.use('TkAgg') root.title("Matplotlib Icon Issue") root.geometry('500x500') frame = Frame(root) frame.pack(pady=20) Label(frame, text="点击按钮查看图表").grid(row=0, column=0, padx=10, pady=5) Button(frame, text="Graph", command=show_graph).grid(row=1, column=0, padx=10, pady=5) root.mainloop()
解决方案2:手动恢复图标与窗口焦点(保留独立图表窗口)
如果一定要保留独立的图表窗口,可以通过绑定关闭事件,在图表关闭后强制激活原Tk应用窗口,重置Dock图标关联。
修改后的核心代码(仅修改show_graph函数):
def show_graph(): # 数据准备与绘图部分和原代码一致,修正xticks问题 a = [90.2, 123.8, 110.2, 108.1, 115.0] b = [100, 100, 100, 100, 100] target = [98, 98, 98, 98, 98] weeks = [0, 1, 2, 3, 4] figure1 = plt.figure(figsize=(4, 2), dpi=200) ax = figure1.add_subplot(111) ax.set_xticks(weeks) ax.plot(weeks, a, '--.', label="A") ax.plot(b, 'r--', label="B") ax.plot(target, 'g--', label="C") ax.legend() ax.set_xlabel('Week') ax.set_ylabel('A', labelpad=1) ax.grid(True, which="both", ls="-") # 获取图表对应的Tk窗口 fig_manager = plt.get_current_fig_manager() tk_graph_window = fig_manager.window # 自定义关闭事件:清理图表并恢复原窗口焦点 def on_graph_close(): figure1.clear() plt.close(figure1) # 强制激活原Tk根窗口 root.lift() root.focus_force() # 通过切换顶层属性触发Dock图标重置 root.call('wm', 'attributes', '.', '-topmost', True) root.call('wm', 'attributes', '.', '-topmost', False) # 绑定关闭事件 tk_graph_window.protocol("WM_DELETE_WINDOW", on_graph_close) figure1.show()
内容的提问来源于stack exchange,提问作者Fab
相关产品推荐
相关产品推荐

