4

I'm trying to create an executable following this tutorial

https://github.com/anthony-tuininga/cx_Freeze/tree/master/cx_Freeze/samples/Tkinter

After some tweaking I'm able to compile the project but when i click the .exe the mouse loading animation fires but nothing ever loads. This questions has been asked previously but was never resolved.

Where to start looking in the code when your .exe doesn't work after cx_freeze?

My app file

from tkinter import *
from tkinter import messagebox

root = Tk()
root.title('Button')
print("something")
new = messagebox.showinfo("Title", "A tk messagebox")
root.mainloop()

my setup.py

import sys
from cx_Freeze import setup, Executable

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

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

setup(name='simple_Tkinter',
      version='0.1',
      description='Sample cx_Freeze Tkinter script',
      executables= [Executable("SimpleTkApp.py", base=base)])

Also I have been manually adding the TCL/TK libraries

set TK_LIBRARY=C:\...\tk8.6  etc

My configuration: python 3.7, cx_Freeze 5.1.1

Any help would be greatly appreciated, I don't even know where to start on this one.

jpeg
  • 2,372
  • 4
  • 18
  • 31
Lloyd
  • 53
  • 6

3 Answers3

2

Try to modify you setup.py as follows:

import sys
from cx_Freeze import setup, Executable

import os
PYTHON_INSTALL_DIR = os.path.dirname(sys.executable)
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')

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'))]

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

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

setup(name='simple_Tkinter',
      version='0.1',
      description='Sample cx_Freeze Tkinter script',
      options={'build_exe': {'include_files': include_files}},
      executables=executables)

This should work for cx_Freeze version 5.1.1 (the current version). In this version, the included modules are in a subdirectory lib of the build directory. If you use 5.0.1 or an earlier version, set

include_files = [os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
                 os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll')]

instead.

See also Getting "ImportError: DLL load failed: The specified module could not be found" when using cx_Freeze even with tcl86t.dll and tk86t.dll added in and python tkinter exe built with cx_Freeze for windows won't show GUI

EDIT:

A further problem is that cx_Freeze has a bug with python 3.7 which is not yet corrected. See Cx_freeze crashing Python3.7.0 . You can find there a link to a bug fix which you should apply manually (according to the OP this solved the problem, see comments).

jpeg
  • 2,372
  • 4
  • 18
  • 31
  • I tried your example (straight copy) but it did not resolve the issue. I am using version 5.1.1 with python 3.7. I just looked at the .whl and all the versions match up. Is there any more information I could provide that might help? – Lloyd Oct 15 '18 at 13:10
  • The information that you use python 3.7. might be relevant. `cx_Freeze` has a bug with python 3.7 which is not yet corrected. See https://stackoverflow.com/a/51692991/8516269 where you can find a link to a bug fix which you should apply manually if this is an option for you. Alternatively, you could try with python 3.6 if this is an option for you. – jpeg Oct 15 '18 at 14:19
  • Furthermore, I'm note sure whether the `from tkinter import *` is totally unproblematic. Have you tried `from tkinter import Tk, messagebox`? – jpeg Oct 15 '18 at 14:23
  • Yes you are correct about the bug, I just stumbled across that when trying an even simpler app, updating my freezer.py fixed the issue. The import all statement doesn't seem to cause any problems. I'm marking your answer as accepted. Thank you for help. – Lloyd Oct 15 '18 at 14:54
1

After trying an even simpler hello world example writing to the console (which also failed) I stumbled across the culprit.

What could be the reason for fatal python error:initfsencoding:unable to load the file system codec?

After updating my freezer.py file with the code found here and using the setup.py provided by jpeg, my example app worked. Thank you both for your swift response.

Lloyd
  • 53
  • 6
0

I have a working setup.py here. Maybe you can try and see if it works after using the same config. Basically sometimes after compiling, the tk and tcl dll/packages are missing and so you need to include them during the setup.

import sys, os
from cx_Freeze import setup, Executable

includes = []

include_files = [r"C:\Users\user\AppData\Local\Programs\Python\Python36-32\DLLs\tcl86t.dll",
                 r"C:\Users\user\AppData\Local\Programs\Python\Python36-32\DLLs\tk86t.dll"]

base = 'Win32GUI' if sys.platform == 'win32' else None

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

setup(name="simple_Tkinter",
      version="0.1",
      options={"build_exe":{"includes":[],"include_files":include_files}},
      description="Sample cx_Freeze Tkinter script",
      executables=[Executable("SimpleTkApp.py",base=base)])
Henry Yik
  • 22,275
  • 4
  • 18
  • 40
  • I've tried this example (adjusted to my path c:\program files x86\...) but the issue was not resolved. The window still does not launch, although you were correct that the DLL's did not get copied over. – Lloyd Oct 15 '18 at 12:59