KeyError: 'TCL_Library' when I use cx_Freeze

KeyError: 'TCL_Library' when I use cx_Freeze

当我使用 cx_Freeze 时,我在构建我的 pygame 程序时得到一个键错误 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")],
    )

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

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 mailinglist it was mentioned:

I have looked into it already and no, it is not just a simple recompile -- or it would have been done already! :-)

It is in progress and it looks like it will take a bit of effort. Some of the code in place to handle things like extension modules inside packages is falling over -- and that may be better solved by dropping that code and forcing the package outside the zip file (another pull request that needs to be absorbed). I should have some time next week and the week following to look into this further. So all things working out well I should put out a new version of cx_Freeze before the end of the year.

但也许你有更多的运气...... Here's the bug report.

只需将其放在 setup.py

的设置之前
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

这对我来说很好。

如果使用 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 目录。现在将 tcl 目录从现有的 Python36 目录(在 C:\ 中)复制到 Python35-32.

然后它工作正常。

除了使用安装特定的绝对路径设置环境变量,如 C:\LOCAL_TO_PYTHON\...,您还可以使用 Python 标准包的 __file__ 属性动态派生必要的路径,如 [=14] =]:

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')

此修复后将创建可执行文件,但当您尝试执行它时可能会得到一个 "DLL not found error" - 至少对于 Python 3.5.3 和 cx_Freeze 5.0.1 Windows 10.

当您添加以下选项时,必要的 DLL 文件将自动从 Python-Installation 目录复制到 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,
      # ...
)

如果使用 python 3.6 时出现以下错误:

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

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

然后它工作正常。

**我执行了这些步骤并在构建目录中创建了一个 .exe 文件,但是如果我尝试单击应用程序,请不要立即在屏幕上快速等待,我的代码在这里 **

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()

need to be modified for cx_Freeze version 5.1.1 or 5.1.0. In these versions of cx_Freeze, packages get frozen into a subdirectory lib of the build directory. The TCL and TK DLLs need to be moved there as well. This can be achieved by passing a tuple (source, destination) to the corresponding entry of the include_files list option (see the cx_Freeze documentation).

总共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,
      # ...
)

初始KeyError问题:

这对我有用 python 3.7 on windows 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 正在工作:

我的应用程序正在运行: