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

使用cx_Freeze将Tkinter脚本转为EXE时添加文件遇问题求助

我来帮你解决cx_Freeze打包Tkinter程序时遇到的额外文件问题,不管是图标无法加载导致EXE打不开,还是数据库文件找不到,核心都是路径适配的问题——打包前后程序的工作路径会发生变化,不能直接用相对路径读取文件。下面分步骤给出解决方案:

1. 解决图标无法加载导致EXE打不开的问题

你当前直接用相对路径'test.ico'加载图标,但打包后程序运行时的工作目录不一定是EXE所在目录,而且cx_Freeze需要正确处理图标文件的路径映射。

第一步:给主脚本添加资源路径适配函数

在Show_file.py的开头加入这个工具函数,它能自动适配打包前后的环境,返回文件的绝对路径:

import sys
import os

def get_resource_path(relative_path):
    """获取资源文件的绝对路径,适配打包前后的运行环境"""
    try:
        # cx_Freeze打包后,资源文件会被放到临时目录,sys._MEIPASS就是这个目录的路径
        base_path = sys._MEIPASS
    except Exception:
        # 未打包时,直接用当前脚本所在的目录
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

第二步:修改图标加载代码

把原来的图标加载代码替换成用上面函数获取的路径:

# 替换 self.wm_iconbitmap('test.ico') 为:
self.wm_iconbitmap(get_resource_path('test.ico'))

第三步:在打包脚本中指定EXE图标

给cx_Freeze.Executable添加icon参数,同时确保base参数正确设置(避免弹出控制台窗口):

executables = [cx_Freeze.Executable("Show_file.py", base=base, icon="test.ico")]
2. 解决Excel数据库文件找不到的问题

同样的道理,读取Excel文件时不能用相对路径,必须用get_resource_path函数获取绝对路径,同时要把Excel文件加入打包列表。

第一步:修改Excel读取代码

假设你原来读取Excel的代码是:

import pandas as pd
df = pd.read_excel('data.xlsx')

替换成:

df = pd.read_excel(get_resource_path('data.xlsx'))

第二步:把Excel文件加入打包配置

在打包脚本的include_files列表中添加你的Excel文件名:

"include_files": ["test.ico", "data.xlsx"]  # 替换成你实际的Excel文件名
完整修改后的代码示例

修改后的主脚本Show_file.py

import sys
import os
import tkinter as tk
import numpy.core._methods, numpy.lib.format

def get_resource_path(relative_path):
    """获取资源文件的绝对路径,适配打包前后的运行环境"""
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

class Main(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.geometry("700x400")
        self.wm_iconbitmap(get_resource_path('test.ico'))
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (StartPage, PageOne):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(StartPage)
    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()
        frame.update_page() # <-- update data on page when you click button
    def get_page(self, page_class):
        return self.frames[page_class]

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label1 = tk.Label(self, text="What are the sizes?")
        label1.pack()
        L1 = tk.Label(self, text="Length :")
        L1.pack()
        self.E1 = tk.Entry(self)
        self.E1.pack()
        button = tk.Button(self, text="Next", command=lambda: controller.show_frame(PageOne))
        button.pack()
    def update_page(self):
        # empty method but I need it
        pass

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label1 = tk.Label(self, text="You have insert")
        label1.pack()
        # create empty label at start
        self.label2 = tk.Label(self, text="")
        self.label2.pack()
        button = tk.Button(self, text="Back", command=lambda: controller.show_frame(StartPage))
        button.pack()
    def update_page(self):
        # update label when page is changed
        page1 = self.controller.get_page(StartPage)
        var = page1.E1.get()
        self.label2['text'] = var

app = Main()
app.mainloop()

修改后的打包脚本

import cx_Freeze
import sys
import matplotlib
import os
import numpy.core._methods
import numpy.lib.format

base = None
if sys.platform=='win32':
    base = "Win32GUI"  # 避免弹出控制台窗口

executables = [cx_Freeze.Executable("Show_file.py", base=base, icon="test.ico")]

cx_Freeze.setup(
    name = "Name",
    options = {
        "build_exe": {
            "packages": ["tkinter","matplotlib"],
            "include_files": ["test.ico", "你的Excel文件名.xlsx"]  # 替换为实际Excel文件名
        }
    },
    version="0.01",
    executables=executables)
验证步骤
  1. 确保图标、Excel文件和两个脚本都放在同一个目录下
  2. 运行打包脚本:python 你的打包脚本名.py build
  3. 进入build目录下的子文件夹,双击生成的EXE文件,就能正常加载图标和读取Excel文件了

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:35:53