【问题标题】:KeyError: 'TCL_Library' when I use cx_FreezeKeyError: 'TCL_Library' 当我使用 cx_Freeze
【发布时间】:2016-06-02 17:00:03
【问题描述】:

当我使用 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")],
    )

【问题讨论】:

    标签: python python-3.x cx-freeze


    【解决方案1】:

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

    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

    我已经研究过了,不,它不仅仅是一个简单的重新编译—— 或者它已经完成了! :-)

    它正在进行中,看起来需要一些努力。一些 用于处理包内扩展模块之类的代码 正在倒下——这可能通过删除该代码更好地解决 强制将包放在 zip 文件之外(另一个需要的拉取请求 被吸收)。我下周和下周应该有时间 进一步调查。所以一切都很好,我应该把 年底前出新版cx_Freeze。

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

    【讨论】:

    • 抱歉让您久等了。谢谢你的帮助,我还没有这个工作。
    • 在 python 3.6.1/2 中也会发生
    • 复制tk86.dlltcl86.dll到二进制路径可以解决运行时错误
    【解决方案2】:

    除了使用安装特定的绝对路径(如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')
    

    在此修复后,将创建可执行文件,但当您尝试执行它时可能会收到“找不到 DLL 错误” - 至少在 Windows 10 上使用 Python 3.5.3 和 cx_Freeze 5.0.1。

    当您添加以下选项时,必要的 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,
          # ...
    )
    

    【讨论】:

    • 哇,效果很好!我什至没有得到DLL not found error,因此无需添加答案第二部分中指定的额外选项。我有 Python 3.6,我的 py-app 使用 Tkinter/TCL。
    • 对于 cx_Freeze 版本 5.1.1,需要将 DLL 复制到构建目录的子目录 lib,请参阅my answer 中的方法。
    【解决方案3】:

    把它放在 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
    

    这对我来说很好。

    【讨论】:

      【解决方案4】:

      如果您在使用 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

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

      【讨论】:

        【解决方案5】:

        如果您在使用 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()
        

        【讨论】:

          【解决方案6】:

          D. L. Müller's answer 需要针对 cx_Freeze 版本 5.1.1 或 5.1.0 进行修改。在这些版本的 cx_Freeze 中,包被冻结到构建目录的子目录 lib 中。 TCL 和 TK DLL 也需要移到那里。这可以通过将元组(source, destination) 传递给include_files 列表选项的相应条目来实现(请参阅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,
                # ...
          )
          

          【讨论】:

            【解决方案7】:

            初始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 正在工作:

            我的应用程序正在运行:

            【讨论】:

              猜你喜欢
              • 2019-10-04
              • 2016-04-28
              • 2020-09-28
              • 1970-01-01
              • 2021-02-01
              • 1970-01-01
              • 1970-01-01
              • 2021-01-30
              • 2020-11-22
              相关资源
              最近更新 更多