首页 > 解决方案 > 构建 tkinter 应用程序时,cx_freeze 不包括 macOS 上的 tcl8.6 和 tk8.6 文件夹

问题描述

我正在尝试在 macOS 上打包一个 tkinter 应用程序。但是,cx_freeze 不包括所需的库文件夹。我无法使用适用于 macOS 的官方 Python 安装程序包构建任何应用程序,因此我决定编译我自己的 Python 构建并将其链接到最新的 tkinter。

我的设置:

自制 tkinter 安装

brew install tcl-tk

Python环境

PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'" MACOSX_DEPLOYMENT_TARGET=10.9 pyenv install 3.8.5
pyenv global 3.8.5
python --version
3.8.5
python -m pip install cx_freeze
python -m pip show cx_freeze
[...]Version: 6.2[...]

Python Tkinter 脚本 - app.py

import tkinter as tk
from tkinter import Frame
from os import path, remove, environ
import sys

class mainWindow(Frame):
    def __init__(self):
        Frame.__init__(self)

if __name__ == "__main__":
    if getattr(sys, 'frozen', False): 
        WorkingDir = path.dirname(sys.executable)
        if sys.platform == "darwin":
            environ['TK_LIBRARY'] = WorkingDir + '/tk8.6/'
            environ['TCL_LIBRARY'] = WorkingDir + '/tcl8.6/'
            print(environ['TCL_LIBRARY'])
            print(environ['TK_LIBRARY'])
    else:
        WorkingDir = path.dirname(path.realpath(__file__))

    root = tk.Tk()
    app = mainWindow()
    root.mainloop()

cx_freeze - setup.py

import sys
from cx_Freeze import setup, Executable


# MacOS
bdist_mac_options = {'bundle_name': 'tkinter app'}

base = None

target = Executable(
    script="app.py",
    base=base,
    targetName="app"
    )

    setup(name = "Tkinter Standalone App",
          version = "0.1",
          author = "Me",
          description = "For Testing Purposes Only",
          options = {"bdist_mac": bdist_mac_options},
          executables = [target])

构建结果

python setup.py bdist_mac

您可以在此处找到构建日志。如您所见,它确实复制了正确的 *.dylibs,但没有包含 tkinter 需要的任何其他文件。如果我在设置 TCL 和 TK_LIBRARY 路径的条件下注释掉上述内容,则使用 open -a 'tkinter app.app' 或 build/ 文件夹中的可执行文件启动应用程序将按预期工作。但是,卸载 tcl-tk 后,我收到以下信息:

    brew uninstall tcl-tk

    xcodeclub@XCodeClubs-Mac-4 MacOS % ./app
Traceback (most recent call last):
  File "/Users/xcodeclub/.pyenv/versions/3.8.5/lib/python3.8/site-packages/cx_Freeze/initscripts/__startup__.py", line 40, in run
    module.run()
  File "/Users/xcodeclub/.pyenv/versions/3.8.5/lib/python3.8/site-packages/cx_Freeze/initscripts/Console.py", line 33, in run
    exec(code,  m.__dict__)
  File "app.py", line 23, in <module>
  File "/Users/xcodeclub/.pyenv/versions/3.8.5/lib/python3.8/tkinter/__init__.py", line 2261, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: Can't find a usable init.tcl in the following directories: 
    /usr/local/Cellar/tcl-tk/8.6.10/lib/tcl8.6 /Users/xcodeclub/.pyenv/lib/tcl8.6 /Users/xcodeclub/lib/tcl8.6 /Users/xcodeclub/.pyenv/library /Users/xcodeclub/library /Users/xcodeclub/tcl8.6.10/library /Users/tcl8.6.10/library



This probably means that Tcl wasn't installed properly.

如果我将丢失的文件复制到executable_path,则从'tkinter app.app'文件夹启动二进制文件有效:

brew install tcl-tk
cp -r /usr/local/Cellar/tcl-tk/8.6.10/lib/tk8.6 tkinter\ app.app/Contents/MacOS/
cp -r /usr/local/Cellar/tcl-tk/8.6.10/lib/tcl8.6 tkinter\ app.app/Contents/MacOS/
brew uninstall tcl-tk

xcodeclub@XCodeClubs-Mac-4 MacOS % ./app
/Users/xcodeclub/Documents/tkinter-app/build/tkinter app.app/Contents/MacOS/tcl8.6/
/Users/xcodeclub/Documents/tkinter-app/build/tkinter app.app/Contents/MacOS/tk8.6/

但是,启动应用程序本身会导致应用程序快速打开然后关闭,而不会出现任何错误消息。有什么我想念的想法吗?我也曾经使用过 cx-freeze 的 include_files 和 include_resources 选项,但这也没有用。

我设法在 Windows 和 Linux 上成功构建了我的 tkinter 应用程序,但几个月来我一直被这个 macOS 问题困扰。任何帮助将不胜感激!

标签: pythonmacostkintercx-freeze

解决方案


推荐阅读