Search code examples
pythonpython-3.xoperating-systemexecx-freeze

Error after converting tkinter program to exe using cx_Freeze and running the exe file


I've spent hours trying to find how to fix this problem but I haven't been able to find anything helpful yet. So I'm trying to convert a tkinter program to exe using cx_Freeze. Everything works well until I try to open the actual exe file Here's is the error report.

My setup file:

import os
import sys
from cx_Freeze import setup, Executable

base = None

if sys.platform == 'win32':
    base = 'Win32GUI'

os.environ['TCL_LIBRARY'] = r"C:\Users\Osborne-Win10\AppData\Local\Programs\Python\Python36\DLLs\tcl86t.dll"
os.environ['TK_LIBRARY'] = r"C:\Users\Osborne-Win10\AppData\Local\Programs\Python\Python36\DLLs\tk86t.dll"

build_options = dict(
    packages=['sys'],
    includes=['tkinter'],
    include_files=[(r'C:\Users\Osborne-Win10\AppData\Local\Programs\Python\Python36\DLLs\tcl86t.dll',
                    os.path.join('lib', 'tcl86t.dll')),
                   (r'C:\Users\Osborne-Win10\AppData\Local\Programs\Python\Python36\DLLs\tk86t.dll',
                    os.path.join('lib', 'tk86t.dll'))]
)

executables = [
    Executable('app.py', base=base)
]

setup(name='simple_Tkinter',
      options=dict(build_exe=build_options),
      version='0.1',
      description='Sample cx_Freeze tkinter script',
      executables=executables,
      )

and my script:

import tkinter as tk

root = tk.Tk()

tk.Label(root, text='Application', font='Tahoma 15 bold italic').pack()

tk.mainloop()

So if you have any idea what could/is causing the error please let me know!


Solution

  • (Answer edited after the OP has modified the question)

    I guess something is wrong with the os.environ definitions. They should point to TCL/TK directories, not to the DLLs. These definitions should read something like:

    os.environ['TCL_LIBRARY'] = r"C:\Users\Osborne-Win10\AppData\Local\Programs\Python\Python36\tcl\tcl8.6"
    os.environ['TK_LIBRARY'] = r"C:\Users\Osborne-Win10\AppData\Local\Programs\Python\Python36\tcl\tk8.6"
    

    Anyway, it would be much better to let the setup script find dynamically the location of the TCL/TK resources as suggested in this answer:

    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')
    
    build_options = dict(
        packages=['sys'],
        includes=['tkinter'],
        include_files=[(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
                        os.path.join('lib', 'tcl86t.dll')),
                       (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
                        os.path.join('lib', 'tk86t.dll'))]
    )