使用cx_freeze构建应用并执行.exe文件后,使用tkinter从我的GUI应用中获得的TreeView无法正常工作

问题描述

我已经创建了一个使用tkinter进行练习的应用程序,该应用程序类似于一个虚拟钱包,可以跟踪您的支出。您可以添加不同类别的存款和取款,然后使用tkinter ttk TreeView小部件将其全部显示在树视图中。这是一张图片,因此更易于理解:

App treeview example

当我像其他任何python文件一样使用main.py文件运行它时,它可以正常运行,但是当我使用cx_freeze将其构建为可执行文件时,即使构建工作且应用程序运行,TreeView小部件的站点通过“历史记录”菜单访问的,不会加载,并且显示为完全空,但不会崩溃或引发任何错误:

App treeview error

这是我的setup.py文件代码:

import sys
import os
from cx_Freeze import setup,Executable


application_title = "Monedero App"
main_python_file = "main.py"

PYTHON_INSTALL_DIR = os.path.dirname(sys.executable)
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR,'tcl','tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR,'tk8.6')

base = None
if sys.platform == "win64":
    base = "Win64GUI"
elif sys.platform == "win32":
    base = "Win32GUI"

options = {
    "build_exe": {
        "packages": ["tkinter","tkinter.ttk","shelve","datetime"],"include_files": [
            "D:\\Programacion\\Projects and exercices\\Monedero\\imagenes\\logo.ico",(os.path.join(PYTHON_INSTALL_DIR,'DLLs','tk86t.dll'),os.path.join('lib','tk86t.dll')),'tcl86t.dll'),'tcl86t.dll')),],}
}

setup(
    name = application_title,version = "0.1",description = "Test 1",options = options,executables = [Executable(main_python_file,base=base)],)

另一个重要的部分是我使用搁置的python库保存数据。我这样做是因为首先我使用sqlite来做,但是我遇到了同样的问题,我认为sqlite可能是问题。现在我不知道可能是什么问题。

在我应该从那里更改某些内容的情况下,我还将附加TreeView小部件配置功能代码:

def configure(self):
    self.parent.refresh()

    try:
        self.historial_frame.destroy()
    except:
        pass

    self.title.config(
        fg = "white",bg = "black",font = ("Arial",30),padx = 110,pady = 20
    )
    self.title.pack(side = tk.TOP,fill = tk.X,expand = tk.YES)

    self.historial_frame = tk.Frame(self)

    style = ttk.Style()
    style.configure("mystyle.Treeview",highlightthickness = 0,bd = 0,font = ('Calibri',11)) # Modify the font of the body
    style.configure("mystyle.Treeview.Heading",13,'bold')) # Modify the font of the headings
    style.layout("mystyle.Treeview",[('mystyle.Treeview.treearea',{'sticky': 'nswe'})]) # Remove the borders

    self.historial = ttk.Treeview(self.historial_frame,columns = ('Fecha','Cantidad','Descripción'),style = "mystyle.Treeview",height = 10)
    self.historial.column("#0",width = 150,stretch = tk.NO)
    self.historial.column("#1",stretch = tk.NO)
    self.historial.column("#2",width = 100,stretch = tk.NO)
    self.historial.column("#3",width = 200,minwidth = 100,stretch = tk.YES)
    self.historial.heading("#0",text = "Categoría",anchor = tk.W)
    self.historial.heading("#1",text = "Fecha",anchor = tk.W)
    self.historial.heading("#2",text = "Cantidad",anchor = tk.W)
    self.historial.heading("#3",text = "Descripción",anchor = tk.W)
    self.historial.grid(row=0,column=0,columnspan=15,padx=10,pady=10,sticky="nsew")

    scrollbar = ttk.Scrollbar(self.historial_frame,orient = tk.VERTICAL,command = self.historial.yview)
    scrollbar.grid(row=0,column=15,sticky="nse",pady="10")
    self.historial.configure(yscrollcommand = scrollbar.set)

    self.parent.import_categories()
    total = self.fill_historial()

    totalLabel = tk.Label(self.historial_frame,text = "Balance total: ")
    totalLabel.config(font = ('Calibri',13))
    totalLabel.grid(row = 1,column = 0,sticky = "w",pady = 10,padx = 5)

    total_dato = tk.StringVar()
    total_dato.set("{:.2f}".format(total) + " €")
    totalLabel_dato = tk.Label(self.historial_frame,textvariable = total_dato,justify = 'left')
    totalLabel_dato.config(font = ('Calibri',13))
    totalLabel_dato.grid(row = 1,column = 1,padx = 5)

    self.historial.tag_configure('odd',font = 'Calibri 13') 

    deleteLabel = tk.Label(self.historial_frame,text = "Eliminar registro: ")
    deleteLabel.grid(row = 1,column = 3,padx = 5)
    deleteButton = tk.Button(self.historial_frame,text="Borrar",command=self.delete_register)
    deleteButton.grid(row = 1,column = 4,padx = 5)
    

    self.historial_frame.pack()
    self.pack(fill = "both")

因此,如果有人对正在发生的事情有所了解,请多多关照。如果需要更多信息,请询问。代码或图像上的西班牙语名称和单词是因为我来自西班牙:)。

谢谢!

解决方法

这里是替代方法,可以使用pyinstaller

在您的终端机中说:

pip install pyinstaller

然后在终端中使用此命令,例如

pyinstaller -F -w -i"path.ico" name.py

在这里

  • -w意味着该程序应该使用Windows窗口,因为它使用GUI
  • -F意味着该程序应制成一个文件而不是目录
  • -i"path.ico"这可用于为您的exe设置图标

并确保使用dist文件夹中的exe,如果您使用任何图像文件,则将exe复制到项目目录。

Take a look at the documentation

希望它清除了您的疑问,如果有任何错误确实让我知道

欢呼

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...