You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关闭含Matplotlib图形的CustomTkinter窗口后报错的解决方案咨询

CustomTkinter集成Matplotlib关闭窗口报错及程序残留问题解决

问题现象

关闭窗口后控制台输出以下错误,程序进程仍在后台持续运行:

invalid command name "2444841565824check_dpi_scaling"
    while executing
"2444841565824check_dpi_scaling"
    ("after" script)
invalid command name "2444841677504update"
    while executing
"2444841677504update"
    ("after" script)

用户提供的示例代码:

from tkinter import *
from customtkinter import *
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
matplotlib.use('TkAgg')

plt.rcParams["figure.facecolor"] = "2b2b2b"
plt.rcParams["axes.facecolor"] = "2b2b2b"
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']
plt.rcParams['mathtext.default'] = 'regular'

root = CTk()
root.geometry('1000x600+200+40')
root.minsize(width=800, height=600)
root.title('Something')
root.state("zoomed")

EquationFrame = CTkFrame(root, height=800,width=500)
EquationFrame.place(relx=0.239 , rely=0.03 , relwidth=0.4*1.8 , relheight=(0.3999*3)- 0.2688)

EquationOutput = Label(EquationFrame)
EquationOutput.place(relx=0.024, rely=0.3004,)

figure = plt.figure(figsize=(13.25, 2))
ax = figure.add_subplot(111)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

canvas = FigureCanvasTkAgg(figure, master=EquationOutput)
canvas.get_tk_widget().pack(side="top", fill="both", expand=True)
canvas._tkcanvas.pack(fill="both", expand=True, side="top")

ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["top"].set_visible(False)
ax.spines["bottom"].set_visible(False)

ax.clear()
ax.text(-0.15, 0.37, f"$(something)^2 * (something)^3$", fontsize=50, fontdict=None).set_color("white")

root.mainloop()

解决方法

错误根源是Matplotlib的FigureCanvasTkAgg组件在窗口关闭时未被正确销毁,导致Tkinter的after定时任务仍尝试调用已释放的组件资源。以下是具体修复步骤:

1. 绑定窗口关闭事件,手动清理资源

给主窗口添加关闭回调函数,在窗口关闭前销毁Matplotlib的Canvas组件,释放相关资源:

def on_closing():
    canvas.get_tk_widget().destroy()
    canvas._tkcanvas.destroy()
    plt.close(figure)  # 若使用plt创建的figure,用此方法关闭;若用Figure类实例,改用figure.close()
    root.destroy()

root.protocol("WM_DELETE_WINDOW", on_closing)

2. 替换原生Tkinter组件为CustomTkinter适配组件

原代码中使用的Label是Tkinter原生组件,换成CTkLabel能更好适配CustomTkinter的环境,避免潜在兼容问题:

EquationOutput = CTkLabel(EquationFrame, text="")
EquationOutput.place(relx=0.024, rely=0.3004)

3. 优化Matplotlib实例创建方式

尽量避免使用plt.figure创建全局状态的figure,改用matplotlib.figure.Figure直接创建实例,减少全局资源干扰:

from matplotlib.figure import Figure

figure = Figure(figsize=(13.25, 2))

完整修复后的代码

from customtkinter import *
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

matplotlib.use('TkAgg')

# 配置Matplotlib样式
matplotlib.rcParams["figure.facecolor"] = "2b2b2b"
matplotlib.rcParams["axes.facecolor"] = "2b2b2b"
matplotlib.rcParams['font.family'] = 'serif'
matplotlib.rcParams['font.serif'] = ['Times New Roman'] + matplotlib.rcParams['font.serif']
matplotlib.rcParams['mathtext.default'] = 'regular'

def on_closing():
    # 销毁Matplotlib相关组件
    canvas.get_tk_widget().destroy()
    canvas._tkcanvas.destroy()
    figure.close()
    root.destroy()

root = CTk()
root.geometry('1000x600+200+40')
root.minsize(width=800, height=600)
root.title('Something')
root.state("zoomed")
root.protocol("WM_DELETE_WINDOW", on_closing)

EquationFrame = CTkFrame(root, height=800, width=500)
EquationFrame.place(relx=0.239, rely=0.03, relwidth=0.4*1.8, relheight=(0.3999*3)-0.2688)

EquationOutput = CTkLabel(EquationFrame, text="")
EquationOutput.place(relx=0.024, rely=0.3004)

figure = Figure(figsize=(13.25, 2))
ax = figure.add_subplot(111)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

# 隐藏所有坐标轴边框
for spine in ax.spines.values():
    spine.set_visible(False)

canvas = FigureCanvasTkAgg(figure, master=EquationOutput)
canvas.get_tk_widget().pack(side="top", fill="both", expand=True)
canvas._tkcanvas.pack(fill="both", expand=True, side="top")

# 添加公式文本
ax.clear()
ax.text(-0.15, 0.37, "$(something)^2 * (something)^3$", fontsize=50, color="white")

root.mainloop()

关于auto-py-to-exe打包的影响

未修复前,打包后的程序关闭窗口后会残留进程,导致系统资源占用,甚至弹出错误提示;修复后,程序能正常关闭,不会出现残留问题,打包后的运行体验与本地调试一致。

内容的提问来源于stack exchange,提问作者Mr. Hussain AL Hussaini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:30:49