KeyError: 'TCL_Library', когда я использую cx_Freeze

Когда я использую cx_Freeze Я получаю ключевую ошибку KeyError: 'TCL_Library'при создании моей программы Pygame. Почему я получаю это и как мне это исправить?

Мой 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")],
    )

5 ответов

Решение

Вы можете обойти эту ошибку, установив переменные среды вручную:

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-файла (еще один запрос на извлечение, который необходимо принять). У меня должно быть время на следующей неделе и следующей неделе, чтобы разобраться в этом подробнее. Так что все работает хорошо, я должен выпустить новую версию cx_Freeze до конца года.

Но, возможно, вам повезет больше... Вот отчет об ошибке.

Вместо установки переменных среды с использованием конкретных абсолютных путей установки, таких как C:\\LOCAL_TO_PYTHON\\... Вы также можете получить необходимые пути динамически, используя __file__ атрибут стандартного пакета Python, как 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 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,
      # ...
)

Просто поместите это перед установкой в ​​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'

Просто создать LOCAL_TO_PYTHON режиссёр C:\ затем создать Python35-32 реж внутри него. Теперь скопируйте tcl реж из существующих Python36 реж (в C:\) в Python35-32,

Тогда все работает нормально.

Если вы получаете следующую ошибку с 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'

Просто создайте каталог LOCAL_TO_PYTHON в C:\, а затем создайте каталог Python35-32 внутри него. Теперь скопируйте tcl dir из существующего Python36 dir (в C:) в Python35-32.

Тогда все работает нормально.

** Я сделал эти шаги и создал файл.exe в директории сборки, но если я пытаюсь нажать кнопку "app", не ждите на экране мгновенно, мои коды здесь **

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

Ответ Д.Л. Мюллера необходимо изменить для версии cx_Freeze 5.1.1 или 5.1.0. В этих версиях cx_Freeze пакеты замораживаются в подкаталоге lib каталога сборки. Библиотеки TCL и TK также должны быть перемещены туда. Это может быть достигнуто путем передачи кортежа (source, destination) к соответствующей записи 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,
      # ...
)

Начальная проблема KeyError:

Это работало для меня с Python 3.7 на 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 работает:

Мое приложение работает:

Другие вопросы по тегам