2

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?

3
  • I don't have mac to test, but you can try to add include 'tcl'; 'tkinter' might not be enough; may be something more needed Commented Jan 21, 2020 at 9:09
  • I will try to add it, and once I can access my colleague's computer I will test it out Commented Jan 21, 2020 at 9:29
  • @Drako I have tried 'tcl' to includes in the setup file, however, I still get the same error Commented Jan 24, 2020 at 12:05

3 Answers 3

4

Same issue (missing init.tcl) on my setup:

  • macOS 10.15.5, venv with Python 3.7.7 interpreter (includes TCL8.6), py2app 0.21
  • It turns out that TCL is not copied neither to venv nor to .app by py2app, so the generated .app is finding TCL in Python installation directory (/Library/Frameworks/Python.framework/Versions/3.7/lib/tcl8.6) on my setup.
    • however this is not available on the setups without Python installation -> error

Solution

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

Next steps

I see 2 main options how to automate it:

  1. In py2app setup file implement a check for the TCL availability in the venv structure and copy it from the system location if not available
  2. Implement it directly in py2app
Sign up to request clarification or add additional context in comments.

3 Comments

Worked for me too! Thanks. However, my tcl8, tcl8.6 and tk8.6 folders were located at /opt/local/lib/ The location can be found by opening python and running the following commands: ``` import tkinter root = tkinter.Tk() print(root.tk.exprstring('$tcl_library')) print(root.tk.exprstring('$tk_library')) ```
Yes, the TCL and TK location will depend on the way Python and TCL has been installed. I've used an installer from python.org.
I've installed Python through macports. However I thought that the information might help someone else with the same problem, which is why I also left some code which can be used to locate the folders.
0

I had the exact same problem as you, except I was using pygame. Here's a quick fix:

Instead of simply python setup.py py2app, try:

python setup.py py2app --packages="encodings"

(For me I did python setup.py py2app --packages="pygame" and it worked)

Comments

0

I had the same Tcl error trying to run .app bundle built in my setup:

  • MacOS BigSur, python3.11, python-tk, venv with python3.11, py2app

As mentioned above, for different TCL/TK locations dependant on your installs, you may simply rely on py2app finding of the tcl path on your machine, which is given as the 1st path in the error log:

  • _tkinter.TclError: Can't find a usable init.tcl in the following directories:

    /opt/local/lib/tcl8.6 .......

With that, open new terminal at <your_venv>/lib directory and link tcl/tk libraries from that path to your venv as follows:

ln -s /opt/local/lib/tcl8.6 tcl8.6
ln -s /opt/local/lib/tk8.6 tk8.6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.