matplotlib捕获close_event后仍关闭窗口,如何改为触发最小化?
解决Matplotlib关闭按钮触发最小化而非关闭窗口的问题
问题原因
Matplotlib的close_event仅作为窗口关闭前的通知事件,无法终止系统默认的窗口关闭流程。即便在事件处理函数中执行了最小化操作,后续Matplotlib仍会完成窗口关闭逻辑,导致窗口被关闭。
解决方案
直接针对每个绘图窗口对应的Tkinter实例,修改其WM_DELETE_WINDOW协议,将默认的关闭行为替换为最小化操作。
修改后的完整代码
import tkinter as tk import numpy as np import matplotlib.pyplot as plt import sys # 生成数据 x = np.linspace(0,1,100) sinx = np.sin(8.0*np.pi*x) cosx = np.cos(8.0*np.pi*x) def showPlot1(): plotMng1.window.deiconify() def hidePlot1(): plotMng1.window.iconify() def showPlot2(): plotMng2.window.deiconify() def hidePlot2(): plotMng2.window.iconify() # 自定义最小化窗口逻辑 def minimize_window(window): window.iconify() def quitAll(): plt.close('all') root.destroy() sys.exit() # 初始化Tk主窗口 root = tk.Tk() plt.ion() # 创建第一个绘图窗口 fig1, axs1 = plt.subplots() axs1.plot(x,sinx,'-', label="sin") axs1.set_xlim(0,1) axs1.set_ylim(-1,1) axs1.legend(loc="upper right") plotMng1 = plt.get_current_fig_manager() # 替换关闭按钮行为为最小化 plotMng1.window.protocol("WM_DELETE_WINDOW", lambda: minimize_window(plotMng1.window)) plotMng1.window.iconify() # 创建第二个绘图窗口 fig2, axs2 = plt.subplots() axs2.plot(x,cosx,'-', label="cos") axs2.set_xlim(0,1) axs2.set_ylim(-1,1) axs2.legend(loc="upper right") plotMng2 = plt.get_current_fig_manager() # 替换关闭按钮行为为最小化 plotMng2.window.protocol("WM_DELETE_WINDOW", lambda: minimize_window(plotMng2.window)) plotMng2.window.iconify() # 主窗口控制按钮 tk.Button(root, text="显示图1",padx = 20, command=showPlot1).pack() tk.Button(root, text="隐藏图1",padx = 20, command=hidePlot1).pack() tk.Button(root, text="显示图2",padx = 20, command=showPlot2).pack() tk.Button(root, text="隐藏图2",padx = 20, command=hidePlot2).pack() tk.Button(root, text="退出",padx = 20, command=quitAll).pack() root.protocol("WM_DELETE_WINDOW", quitAll) root.mainloop()
关键修改说明
- 移除
close_event绑定:放弃依赖Matplotlib的事件通知,直接操作底层Tkinter窗口对象。 - 覆盖窗口协议:通过
window.protocol("WM_DELETE_WINDOW", 函数)将系统默认的关闭操作替换为自定义的最小化逻辑。 - 针对性处理窗口:使用lambda表达式传递当前窗口对象,确保点击哪个窗口的关闭按钮就最小化哪个窗口;若需要点击任意关闭按钮都最小化所有窗口,可修改lambda内的逻辑为:
lambda: (plotMng1.window.iconify(), plotMng2.window.iconify())
内容的提问来源于stack exchange,提问作者Carl Houtman
相关产品推荐
相关产品推荐

