I have a tkinter application, which I would like to distribute to my colleagues, who do not have python installed. I use py2app with the following setup.py file
from setuptools import setup
import sys
sys.setrecursionlimit(5000)
#APP would be the name of the file your code is in.
APP = ['Doughnut_stress.py']
DATA_FILES = ['C20.icns']
#The Magic is in OPTIONS.
OPTIONS = {
'packages': ['tkinter', 'matplotlib'],
'includes': ['tkinter'],
'argv_emulation': False,
'iconfile': 'C20.icns', #change app.icns to the image file name!!!
'plist': {
'CFBundleName': 'Axial bearing program',
'CFBundleDisplayName': 'Axial bearing program',
'CFBundleGetInfoString': "Calculates C20 axial bearing",
'CFBundleVersion': "0.0.0",
'CFBundleShortVersionString': "0.0.0",
'NSHumanReadableCopyright': u"Copyright © 2020, Component 2.0 A/S, All Rights Reserved"
}
}
setup(
app=APP,
name='Axial bearing program', #change to anything
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
I then use
python setup.py py2app
to compile the program into an app. Note I have symlinked python to python3. My python 3 is version 3.7.5 and is installed through MacPorts. py2app is version 0.20, and tkinter is version 8.6
The program compiles fine, and I can run it from terminal, or just double-click on the app file, and it works as intended.
However, when I send it to my colleague and try to open it from his computer by double-clicking the app, I get a pop up where I can choose to "Open Console" or "Terminate". If I run the program through terminal (by running APP_NAME.app/Contents/MacOS/APP_NAME) I get the following error
Traceback (most recent call last):
File "/Users/prm/Downloads/Component 2.0 axial bearing program.app/Contents/Resources/__boot__.py", line 416, in <module>
_run()
File "/Users/prm/Downloads/Component 2.0 axial bearing program.app/Contents/Resources/__boot__.py", line 394, in _run
exec(compile(source, path, "exec"), globals(), globals())
File "/Users/prm/Downloads/Component 2.0 axial bearing program.app/Contents/Resources/Doughnut_stress.py", line 31, in <module>
root = Tk()
File "tkinter/__init__.pyc", line 2023, in __init__
_tkinter.TclError: Can't find a usable init.tcl in the following directories:
/opt/local/lib/tcl8.6 {/Users/prm/Downloads/Component 2.0 axial bearing program.app/Contents/lib/tcl8.6} {/Users/prm/Downloads/Component 2.0 axial bearing program.app/lib/tcl8.6} {/Users/prm/Downloads/Component 2.0 axial bearing program.app/Contents/library} {/Users/prm/Downloads/Component 2.0 axial bearing program.app/library} {/Users/prm/Downloads/Component 2.0 axial bearing program.app/tcl8.6.9/library} /Users/prm/Downloads/tcl8.6.9/library
This probably means that Tcl wasn't installed properly.
2020-01-20 15:54:28.439 Component 2.0 axial bearing program[34251:2906750] Component 2.0 axial bearing program Error
I can also run the included python file in APP_NAME.app/Contents/MacOS/python, which yield this error
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
Current thread 0x000000010d0f8dc0 (most recent call first):
Abort trap: 6
Someone else posted about this on Reddit some time ago, but no answer came up https://www.reddit.com/r/learnpython/comments/c1on6f/py2app_in_a_mac_without_python/
How can I fix this, so I can distribute my python application?
Same issue (missing init.tcl) on my setup:
When I've manually copied:
- /Library/Frameworks/Python.framework/Versions/3.7/lib/tcl8
- /Library/Frameworks/Python.framework/Versions/3.7/lib/tcl8.6
- /Library/Frameworks/Python.framework/Versions/3.7/lib/tk8.6
to
- path_to_venv/lib
py2app will take it from there and store it in the .app in this location:
- path_to_project/dist/myApp.app/Contents/Resources/lib/
and from here it is found by the python code
I see 2 main options how to automate it: