tkinter 程序使用 cx_Freeze 编译,但程序不会启动

Posted

技术标签:

【中文标题】tkinter 程序使用 cx_Freeze 编译,但程序不会启动【英文标题】:tkinter program compiles with cx_Freeze but program will not launch 【发布时间】:2018-10-12 19:06:11 【问题描述】:

我正在尝试按照本教程创建一个可执行文件

https://github.com/anthony-tuininga/cx_Freeze/tree/master/cx_Freeze/samples/Tkinter

经过一些调整后,我能够编译项目,但是当我单击 .exe 时,鼠标加载动画会触发,但不会加载任何内容。以前有人问过这个问题,但从未得到解决。

Where to start looking in the code when your .exe doesn't work after cx_freeze?

我的应用文件

from tkinter import *
from tkinter import messagebox

root = Tk()
root.title('Button')
print("something")
new = messagebox.showinfo("Title", "A tk messagebox")
root.mainloop()

我的 setup.py

import sys
from cx_Freeze import setup, Executable

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

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

setup(name='simple_Tkinter',
      version='0.1',
      description='Sample cx_Freeze Tkinter script',
      executables= [Executable("SimpleTkApp.py", base=base)])

我也一直在手动添加 TCL/TK 库

set TK_LIBRARY=C:\...\tk8.6  etc

我的配置:python 3.7、cx_Freeze 5.1.1

任何帮助将不胜感激,我什至不知道从哪里开始。

【问题讨论】:

【参考方案1】:

尝试修改你setup.py如下:

import sys
from cx_Freeze import setup, Executable

import os
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, 'tcl', 'tk8.6')

include_files = [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
                 (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))]

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

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

setup(name='simple_Tkinter',
      version='0.1',
      description='Sample cx_Freeze Tkinter script',
      options='build_exe': 'include_files': include_files,
      executables=executables)

这应该适用于cx_Freeze 版本 5.1.1(当前版本)。在此版本中,包含的模块位于构建目录的子目录lib 中。如果您使用的是 5.0.1 或更早的版本,请设置

include_files = [os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
                 os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll')]

改为。

另请参阅Getting "ImportError: DLL load failed: The specified module could not be found" when using cx_Freeze even with tcl86t.dll and tk86t.dll added in 和 python tkinter exe built with cx_Freeze for windows won't show GUI

编辑:

另一个问题是cx_Freeze 在 python 3.7 中存在一个尚未更正的错误。见Cx_freeze crashing Python3.7.0。您可以在那里找到一个指向您应该手动应用的错误修复的链接(根据 OP 这解决了问题,请参阅 cmets)。

【讨论】:

我试过你的例子(直接复制),但它没有解决问题。我将 5.1.1 版与 python 3.7 一起使用。我只是查看了 .whl 并且所有版本都匹配。还有什么我可以提供的可能有帮助的信息吗? 你使用python 3.7的信息。可能是相关的。 cx_Freeze 在 python 3.7 中存在一个尚未更正的错误。请参阅***.com/a/51692991/8516269,您可以在其中找到错误修复的链接,如果这是您的选择,您应该手动应用该修复。或者,如果这是您的选择,您可以尝试使用 python 3.6。 此外,我注意到from tkinter import * 是否完全没有问题。你试过from tkinter import Tk, messagebox吗? 是的,您对这个错误的看法是正确的,我只是在尝试更简单的应用程序时偶然发现了这一点,更新我的 freezer.py 解决了这个问题。 import all 语句似乎没有引起任何问题。我将您的答案标记为已接受。谢谢你的帮助。【参考方案2】:

在尝试了一个更简单的 hello world 示例写入控制台后(也失败了),我偶然发现了罪魁祸首。

What could be the reason for fatal python error:initfsencoding:unable to load the file system codec?

在使用找到的代码 here 更新我的 freezer.py 文件并使用 jpeg 提供的 setup.py 后,我的示例应用程序工作了。谢谢你们两位的迅速反应。

【讨论】:

【参考方案3】:

我在这里有一个可用的 setup.py。也许您可以尝试在使用相同的配置后查看它是否有效。基本上有时在编译后,tk 和 tcl dll/packages 会丢失,因此您需要在安装过程中包含它们。

import sys, os
from cx_Freeze import setup, Executable

includes = []

include_files = [r"C:\Users\user\AppData\Local\Programs\Python\Python36-32\DLLs\tcl86t.dll",
                 r"C:\Users\user\AppData\Local\Programs\Python\Python36-32\DLLs\tk86t.dll"]

base = 'Win32GUI' if sys.platform == 'win32' else None

os.environ['TCL_LIBRARY'] = r'C:\Users\user\AppData\Local\Programs\Python\Python36-32\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Users\user\AppData\Local\Programs\Python\Python36-32\tcl\tk8.6'

setup(name="simple_Tkinter",
      version="0.1",
      options="build_exe":"includes":[],"include_files":include_files,
      description="Sample cx_Freeze Tkinter script",
      executables=[Executable("SimpleTkApp.py",base=base)])

【讨论】:

我试过这个例子(调整到我的路径 c:\program files x86\...)但问题没有解决。窗口仍然没有启动,虽然你是正确的 DLL 没有被复制过来。

以上是关于tkinter 程序使用 cx_Freeze 编译,但程序不会启动的主要内容,如果未能解决你的问题,请参考以下文章

将 cx_freeze 与 tkinter 一起使用时出错

exit() 不适用于 cx_freeze

使用 cx_freeze 为 tkinter 接口创建 .exe 文件

使用 cx_freeze 将脚本转换为 .exe 时如何包含 tkinter?

cx_Freeze 应用程序找不到 tk.tcl

cx_freeze 错误:找不到模块 tkinter