Python py2exe window showing (tkinter) Python py2exe window showing (tkinter) tkinter tkinter

Python py2exe window showing (tkinter)


I ended up encountering this same issue, my solution involved doing the following:

Add"dll_excludes": ["tcl85.dll", "tk85.dll"],

in your options = {...}

and then manually copy those two DLLs from

PYTHON_PATH\DLLs\ (in my case C:\Python27\DLLs)

to the location of your exe and try running it.


An alternative to dll_excludes and manual copying is to patch py2exe to know these files have to be placed directly in the dist directory.

Inside build_exe.py, there's a class called py2exe, which contains a list dlls_in_exedir for dll that have to go there. This list is set during a function named plat_prepare, and you can add the tclXX.dll and tkXX.dll files to it to make sure they are copied correctly.

Of course, unless you're the only one who will ever build this, you don't necessarily know which Tcl and Tk version you need to bundle - someone might have built their Python themselves, or are using an older Python with older DLLs. Therefore, you'll need to check which versions the system is actually using. py2exe actually already does this in a different place: by importing the internal _tkinter module (the actual Tk interface, usually a DLL) and accessing TK_VERSION and TCL_VERSION, which you can then use to generate and add the correct filenames.

If others are supposed to build your application, you probably don't want to make them modify their py2exe install, so here's how you can monkeypatch it from your setup.py:

import py2exepy2exe.build_exe.py2exe.old_prepare = py2exe.build_exe.py2exe.plat_preparedef new_prep(self):  self.old_prepare()  from _tkinter import TK_VERSION, TCL_VERSION  self.dlls_in_exedir.append('tcl{0}.dll'.format(TCL_VERSION.replace('.','')))  self.dlls_in_exedir.append('tk{0}.dll'.format(TK_VERSION.replace('.','')))py2exe.build_exe.py2exe.plat_prepare = new_prep

This even works with bundle_files=1 on Windows 7.


If you have only one version the you can copy files with via data_file. Below a full example:

  • WinXP
  • Python2.7.6
  • tk8.5
  • tcl8.5
  • tix8.4.3
  • py2exe 0.6.9

foo.py:

# -*- coding: iso-8859-1 -*-import Tkinter"""sets TCL_LIBRARY, TIX_LIBRARY and TK_LIBRARY - see installation Lib\lib-tk\FixTk.py"""Tkinter._test()

Setup.py :

# -*- coding: iso-8859-1 -*-from distutils.core import setupimport py2exeimport sysimport osimport os.pathsys.argv.append ('py2exe')setup (    options    =         {'py2exe':             { "bundle_files" : 1    # 3 = don't bundle (default)                                      # 2 = bundle everything but the Python interpreter                                      # 1 = bundle everything, including the Python interpreter            , "compressed"   : False  # (boolean) create a compressed zipfile            , "unbuffered"   : False  # if true, use unbuffered binary stdout and stderr            , "includes"     :                 [ "Tkinter", "Tkconstants"                ]            , "excludes"      : ["tcl", ]            , "optimize"     : 0  #-O            , "packages"     :                 [                 ]            , "dist_dir"     : "foo"            , "dll_excludes": ["tcl85.dll", "tk85.dll"]            ,                           }        }    , windows    =         ["foo.py"        ]    , zipfile    = None    # the syntax for data files is a list of tuples with (dest_dir, [sourcefiles])    # if only [sourcefiles] then they are copied to dist_dir     , data_files = [   os.path.join (sys.prefix, "DLLs", f)                    for f in os.listdir (os.path.join (sys.prefix, "DLLs"))                    if  (   f.lower ().startswith (("tcl", "tk"))                        and f.lower ().endswith ((".dll", ))                       )                    ]     , )