当我使用cx_Freeze时出现KeyError: 'TCL_Library'错误

47
当我使用 cx_Freeze 编译我的 pygame 程序时,出现了一个 keyerror KeyError: 'TCL_Library'。我为什么会遇到这个问题,如何解决?
下面是我的 setup.py:
from cx_Freeze import setup, Executable

setup(
    name = "Snakes and Ladders",
    version = "0.9",
    author = "Adam",
    author_email = "Omitted",
    options = {"build_exe": {"packages":["pygame"],
                         "include_files": ["main.py", "squares.py",
                         "pictures/Base Dice.png", "pictures/Dice 1.png",
                         "pictures/Dice 2.png", "pictures/Dice 3.png",
                         "pictures/Dice 4.png", "pictures/Dice 5.png",
                         "pictures/Dice 6.png"]}},
    executables = [Executable("run.py")],
    )
7个回答

70

您可以通过手动设置环境变量来解决此错误:

set TCL_LIBRARY=C:\Program Files\Python35-32\tcl\tcl8.6
set TK_LIBRARY=C:\Program Files\Python35-32\tcl\tk8.6

你也可以在 setup.py 脚本中这样做:

os.environ['TCL_LIBRARY'] = r'C:\Program Files\Python35-32\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Program Files\Python35-32\tcl\tk8.6'

setup([..])

但我发现实际上运行程序不起作用。在cx_freeze邮件列表中提到:

我已经研究过了,不,这不是简单的重新编译——否则早就完成了!:-)

它正在进行中,看起来需要花费一些努力。一些处理包中扩展模块等内容的代码出现问题,可能最好的解决方法是删除该代码并强制将包放在zip文件之外(另一个需要吸收的pull request)。下周和接下来的一周我应该有一些时间来进一步研究这个问题。所以如果一切顺利,我应该在年底之前发布cx_Freeze的新版本。

但也许你会更幸运......这是错误报告


抱歉让您久等了。感谢您的帮助,我还没有让它正常工作。 - Orange1861
8
也发生在Python 3.6.1/2版本中。 - dgrat
1
tk86.dlltcl86.dll 复制到二进制路径可以解决运行时错误。 - PaleNeutron

36

不要使用安装特定的绝对路径(例如C:\\LOCAL_TO_PYTHON\\...)设置环境变量,而是可以通过Python标准包中的__file__属性动态地派生必要的路径,例如os

import os.path
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
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')

修改后,可创建可执行文件,但在尝试在Windows 10上使用Python 3.5.3和cx_Freeze 5.0.1运行时,可能会出现“未找到DLL文件”的错误。

当您添加以下选项时,必要的DLL文件将自动从Python安装目录复制到cx-Freeze的构建输出中,然后您应该能够运行您的Tcl/Tk应用程序:

options = {
    'build_exe': {
        'include_files':[
            os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
            os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
         ],
    },
}

# ...

setup(options = options,
      # ...
)

哇,这个完美地工作了!我甚至没有收到“DLL未找到错误”的提示,所以不需要按照你回答的第二部分指定额外选项。我的Python版本是3.6,我的py-app使用Tkinter/TCL。 - Alex
对于cx_Freeze版本5.1.1,DLL文件需要复制到构建目录的子目录“lib”中,请参见我的答案中的操作步骤。 - jpeg

15

在setup.py的setup之前添加这个

import os

os.environ['TCL_LIBRARY'] = "C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = "C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tk8.6"

然后运行它:

python setup.py bdist_msi

这对我来说很有效。


6
如果您在使用Python 3.6时遇到以下错误:
copying C:\LOCAL_TO_PYTHON\Python35-32\tcl\tcl8.6 -> build\exe.win-amd64-3.6\tcl
error: [Errno 2] No such file or directory: 'C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6'

只需在C:\中创建LOCAL_TO_PYTHON目录,然后在其中创建Python35-32目录。现在将现有C:\中的Python36目录中的tcl目录复制到Python35-32中即可。

然后它就可以正常工作了。


0

D. L. Müller's answer需要修改为cx_Freeze 5.1.1或5.1.0版本。 在这些版本的cx_Freeze中,包被冻结到构建目录的子目录lib中。 TCL和TK DLL也需要移动到那里。这可以通过将元组(源,目标)传递给include_files列表选项的相应条目来实现(请参阅cx_Freeze文档)。

总之,setup.py脚本需要进行以下修改:

import os.path
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
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')

# ...

options = {
    'build_exe': {
        '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'))
         ],
    },
}

# ...

setup(options = options,
      # ...
)

0

如果您在使用Python 3.6时遇到以下错误:

复制 C:\LOCAL_TO_PYTHON\Python35-32\tcl\tcl8.6 -> build\exe.win-amd64-3.6\tcl error: [Errno 2] No such file or directory: 'C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6'

只需在C盘中创建LOCAL_TO_PYTHON目录,然后在其中创建Python35-32目录。现在将现有Python36目录(位于C:)中的tcl目录复制到Python35-32中。

然后它就可以正常工作了。

**我按照这些步骤创建了一个.exe文件并将其放入build目录,但是如果我尝试单击应用程序,它不会在屏幕上等待,而是立即快速消失,我的代码在这里**

from tkinter import *
import socket



window=Tk()
window.geometry("400x150")
window.title("IpConfiger")
window.config(background="black")

def goster():
    x=socket.gethostbyname(socket.gethostname())
    label=Label(window,text=x,fg="green",font=("Helvetica",16))
    label.pack()
def information():
    info=Label(window,text="Bu program anlık ip değerini 
    bastırır.",fg="green",font=("Helvetica",16),bg="black")
    info.pack()


information()
tikla=Button(window,text="ip göster",command=goster)

tikla.pack()

0

初始的KeyError问题:

KeyError

这在我的windows 7上的python 3.7中起作用:

from cx_Freeze import setup, Executable
import os
import sys

where = os.path.dirname(sys.executable)


os.environ['TCL_LIBRARY'] = where+"\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = where+"\\tcl\\tk8.6"

build_exe_options = {"include_files": [where+"\\DLLs\\tcl86t.dll", where+"\\DLLs\\tk86t.dll"]}  


setup(
    name = "SudoCool",
    version = "0.1",
    description = "Programme de SUDOKU",
    options={"build_exe": build_exe_options},  
    executables = [Executable("sudoku.py")]
) 

现在cx_Freeze正在工作中: 它正在工作

enter image description here

enter image description here

我的应用程序正在运行: 输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接