嵌入Matplotlib的Tkinter程序关闭主窗口后进程仍运行,原因何在?
问题原因及解决方案
原因分析
关闭Tkinter窗口后进程残留,核心问题是Matplotlib的pyplot模块全局状态未被清理:
- 你用
plt.figure()创建图表时,pyplot会在后台维护对该figure的全局引用,即使Tkinter窗口销毁,这些资源也不会自动释放,导致进程无法正常退出。 - Tkinter默认的窗口关闭行为只会销毁窗口组件,但不会主动清理Matplotlib的后台绘图资源和线程。
解决方法
通过两个关键调整彻底解决进程残留问题:
- 改用Matplotlib面向对象的方式创建图表,避免依赖pyplot的全局状态;
- 给Tkinter窗口绑定关闭事件,主动清理Matplotlib资源并销毁窗口。
修改后的完整代码
import matplotlib.backends.backend_tkagg as tkagg import matplotlib.figure import matplotlib import tkinter as tk matplotlib.use('TkAgg') def plot_canvas(master): points = [(0, 0), (10, 0), (10, 25), (20, 25), (25, 0)] # 改用面向对象方式创建Figure,不依赖pyplot全局状态 fig = matplotlib.figure.Figure(figsize=(5, 4)) ax = fig.add_subplot(111) ax.plot([x[0] for x in points], [x[1] for x in points], marker='.', linestyle='-') return tkagg.FigureCanvasTkAgg(fig, master=master).get_tk_widget() m = tk.Tk() # 绑定窗口关闭事件,主动清理资源 def on_window_close(): # 关闭所有Matplotlib图表资源 matplotlib.pyplot.close('all') m.destroy() m.protocol("WM_DELETE_WINDOW", on_window_close) wgt = plot_canvas(m) wgt.grid() m.mainloop() # 主循环结束后再次确保清理所有Matplotlib资源 matplotlib.pyplot.close('all')
额外说明
如果不想完全抛弃plt接口,也可以只保留绑定关闭事件的逻辑,但面向对象的方式更适合嵌入GUI应用,能避免全局状态带来的资源泄漏问题。
内容的提问来源于stack exchange,提问作者Paweł Pietraszko
相关产品推荐
相关产品推荐

