web-dev-qa-db-fra.com

KeyError: 'TCL_Library' lorsque j'utilise cx_Freeze

Quand j'utilise cx_Freeze Je reçois une erreur de clé KeyError: 'TCL_Library' tout en construisant mon programme pygame. Pourquoi est-ce que je reçois ceci et comment je le répare?

Mon setup.py est ci-dessous:

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")],
    )
46
Orange1861

Vous pouvez contourner cette erreur en définissant les variables d'environnement manuellement:

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

Vous pouvez aussi le faire dans le setup.py script:

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([..])

Mais j’ai constaté que l’exécution du programme ne fonctionnait pas. Sur le cx_freeze mailinglist il a été mentionné :

Je l'ai déjà examiné et non, il ne s'agit pas d'une simple recompilation - sinon, cela aurait déjà été fait! :-)

Il est en cours et il semble que cela demandera un peu d'effort. Une partie du code en place pour gérer des choses telles que les modules d'extension dans les packages est en train de tomber - et cela pourrait être mieux résolu en laissant tomber ce code et en forçant le package en dehors du fichier Zip (une autre demande d'extraction à absorber). Je devrais avoir un peu de temps la semaine prochaine et la semaine suivante pour approfondir cette question. Donc, tout va bien, je devrais sortir une nouvelle version de cx_Freeze avant la fin de l'année.

Mais peut-être avez-vous plus de chance ... Voici le rapport de bogue .

69
Martin Tournoij

Au lieu de définir les variables d'environnement à l'aide de chemins absolus spécifiques à l'installation, tels que C:\\LOCAL_TO_PYTHON\\... vous pouvez également extraire dynamiquement les chemins nécessaires en utilisant le __file__ attribut de Python comme 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')

Après cette correction, le fichier exécutable sera créé, mais vous obtiendrez probablement une "erreur de DLL non trouvée" lorsque vous essayez de l'exécuter - du moins avec Python 3.5.3 et cx_Freeze 5.0.1 sous Windows 10.

Lorsque vous ajoutez les options suivantes, les fichiers DLL nécessaires sont automatiquement copiés du répertoire d'installation de Python dans la sortie de génération de cx-Freeze. Vous devriez pouvoir exécuter votre application 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,
      # ...
)
35
D. L. Müller

Il suffit de mettre cela avant la configuration à 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"

Et lancez-le:

python setup.py bdist_msi

CA marchait bien pour moi.

14
Guilherme

Si vous obtenez une erreur de suivi avec 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'

Créez simplement LOCAL_TO_PYTHON dir dans C:\ puis créer Python35-32 dir à l'intérieur. Maintenant, copiez tcl dir à partir de Python36 dir (dans C:\) en Python35-32.

Ensuite ça marche bien.

5
Ben Wills

Réponse de D. L. Müller besoin d'être modifié pour la version 5.1.1 ou 5.1.0 de cx_Freeze. Dans ces versions de cx_Freeze, les packages sont gelés dans un sous-répertoire lib du répertoire de construction. Les DLL TCL et TK doivent également y être déplacées. Cela peut être réalisé en passant un Tuple (source, destination) À l'entrée correspondante de l'option de liste include_files (Voir le documentation cx_Freeze ).

Au total, le script setup.py Doit être modifié comme suit:

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
jpeg

Si vous obtenez une erreur de suivi avec python 3.6:

copier C:\LOCAL_TO_PYTHON\Python35-32\tcl\tcl8.6 -> build\exe.win-AMD64-3.6\tcl Erreur: [Errno 2] No such file or directory: 'C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6'

Créez simplement le répertoire LOCAL_TO_PYTHON dans C: \, puis créez le répertoire Python35-32 à l’intérieur. Maintenant, copiez le répertoire tcl du répertoire Python36 existant (en C :) dans Python35-32.

Ensuite ça marche bien.

** J'ai fait ces étapes et créé un fichier .exe dans le répertoire de construction, mais si j'essaie de cliquer sur l'application, n'attendez pas sur l'écran instantanément, mes codes ici **

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
Onur Çakır