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

GUI绘图程序在Spyder/CMD正常运行,打包为.exe后异常崩溃

解决cx_Freeze打包Matplotlib-Tkinter程序点击Plot崩溃的问题

首先,我注意到你的代码本身存在几个变量作用域和方法调用的问题,这些问题在IDE环境中可能因环境兼容性没暴露,但打包后会直接导致崩溃;另外cx_Freeze对Matplotlib的打包需要额外配置资源文件,我会一步步帮你解决:

一、修正主程序代码的错误

先修复代码里的逻辑和API调用问题,确保程序本身的健壮性:

import tkinter as tk
from tkinter import ttk, messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure

class DataPlotter:
    def __init__(self, master):
        self.master = master  # 把父窗口实例保存为类属性,后续方法可直接调用
        master.geometry('300x100+200+100')
        master.title('Data Plotter')
        master.resizable(False,False)
        
        # 将按钮创建逻辑移入__init__,直接绑定实例方法无需lambda
        ttk.Button(master, text='Plot', command=self.Run).pack(anchor='center')
        
    def PlotFigure(self, fig):
        # 使用保存的父窗口实例创建新窗口
        self.Window = tk.Toplevel(self.master)
        self.canvas = FigureCanvasTkAgg(fig, self.Window)
        self.canvas.draw()  # 替换过时的show(),使用matplotlib推荐的draw()方法
        self.frametool = tk.Frame(self.Window)
        # 替换已弃用的NavigationToolbar2TkAgg为NavigationToolbar2Tk
        self.toolbar = NavigationToolbar2Tk(self.canvas, self.frametool)
        self.toolbar.update()
        self.frametool.pack(side=tk.TOP, fill=tk.BOTH)
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        # 无需重复打包canvas._tkcanvas,get_tk_widget()已返回该组件
        
    def Run(self):
        try:
            app = Plotter(x=range(0,10), y=range(0,10))
            self.PlotFigure(app.plotting())  # 正确调用类的实例方法
        except Exception as ex:
            messagebox.showinfo('Caught Error','Exception caught: ' + str(ex))

class Plotter(object):
    def __init__(self, x=None, y=None):
        self.x = x
        self.y = y
        
    def plotting(self):
        fig = Figure()
        ax = fig.add_subplot(111)
        ax.plot(self.x, self.y, 'o-')
        return fig

def main():
    root = tk.Tk()
    root.grab_set()
    root.focus()
    DataPlotter(root)
    root.mainloop()

if __name__ == "__main__":
    main()

主要修正点:

  • 在DataPlotter.__init__中保存父窗口实例,避免后续方法找不到master变量
  • 修正按钮的方法绑定逻辑,直接传递实例方法而非lambda包装
  • 替换matplotlib中已弃用的Toolbar类和显示方法,适配新版本API
  • 恢复异常捕获逻辑,方便打包后排查运行时错误

二、修正cx_Freeze的setup配置

cx_Freeze打包Matplotlib时,必须手动包含依赖的资源文件,否则会因缺失字体、配置文件导致崩溃,更新后的setup.py如下:

from cx_Freeze import setup, Executable
import sys
import os
import matplotlib

# 设置tkinter的库文件路径,请确保路径与你的Anaconda环境一致
os.environ['TCL_LIBRARY'] = r'C:\ProgramData\Anaconda3\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\ProgramData\Anaconda3\tcl\tk8.6'

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'  # 隐藏命令行窗口,仅显示GUI

# 获取matplotlib的资源文件目录
matplotlib_data_files = matplotlib.get_data_path()

build_exe_options = {
    "packages": ["os", "tkinter", "matplotlib"],
    "include_files": [
        # 复制tkinter的核心dll文件到打包目录
        (os.path.join(os.environ['TCL_LIBRARY'], 'tcl86t.dll'), 'tcl86t.dll'),
        (os.path.join(os.environ['TK_LIBRARY'], 'tk86t.dll'), 'tk86t.dll'),
        # 包含matplotlib的所有资源文件(字体、配置等)
        (matplotlib_data_files, 'matplotlib/mpl-data'),
    ],
    # 排除不必要的测试模块,减少打包体积
    "excludes": ["matplotlib.tests", "numpy.tests"]
}

executables = [Executable('Data_Plotter.py', base=base)]

setup(
    name = "Data_Plotter",
    options = {"build_exe": build_exe_options},
    version = "1.0",
    description = "This program plots data and displays the graph in a new window",
    executables = executables
)

主要配置修正点:

  • 添加include_files,手动复制tkinter的dll文件,避免运行时找不到核心库
  • 包含matplotlib的mpl-data目录,该目录包含绘图必需的字体和配置文件
  • 排除测试模块,减少打包后的文件体积和冗余内容

三、打包与测试步骤

  1. 确保激活你的Anaconda环境,安装cx_Freeze:pip install cx_Freeze
  2. 将修正后的Data_Plotter.py和setup.py放在同一目录
  3. 打开命令提示符,切换到该目录,执行打包命令:python setup.py build
  4. 进入build目录下的子文件夹,运行生成的Data_Plotter.exe,点击Plot按钮即可正常显示图形

如果仍有问题,可以暂时将base设为None,这样运行exe时会显示命令行窗口,能看到具体的错误信息,方便进一步排查。

内容的提问来源于stack exchange,提问作者Sammyjay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:37:40