我正在尝试使用 pyinstaller 将我的项目打包成可执行文件。 main.py,我的程序,应该在我运行 exe 文件时运行。因为程序必须以某种方式运行,而无需用户(无论如何都不是开发人员)需要安装模块和 python 本身。如果有更好/更简单的方法请告诉我。
我使用
pip install tkinterdnd2
安装了 tkinterdnd2。
不确定这是否有必要,但这里是程序的目录:(png仅用于我的程序,我不认为这是罪魁祸首):
Folder
- cardiologist.png
- img.png
.
. # a couple more pngs
.
- main.py
- patients' data csv.csv
- patients' data xlsx test.xlsx
- sample.xlsx
- sun-valley.tcl #this file and the 'theme' folder below are for my program's theme, also don't think these are the culprit
- theme
- dark
- a lot of pngs...
- dark.tcl
- light
- a lot of pngs...
- light.tcl
Pyinstaller 按预期创建了 2 个文件,
build
和 dist
。
build
- main
- base_library.zip
- certifi
- IPython
- jedi
- (some other files)
.
. a lot of .dylib files
.
- main # exe file to execute to run program
- matplotlib (this and next 4 are folders)
- numpy
- pandas
- parso
- PIL
- Python # exe file, don't know what this was created for
- (some more folders)
- tcl (this and next 2 are folders)
- tcl8
- 8.4
- platform
- .tm file
- .tm file
- 8.5
- 2 .tm files
- 8.6
- .tm file
- tdbc
- .tm file
- tkdnd2.8 (tried renaming to just tkdnd but same error)
- tk
- ttkwidgets
- 2 other folders
我使用的命令:
python -m PyInstaller main.py. # without python -m, 'command not found error' would happen
运行生成的exe时出错:
Traceback (most recent call last):
File "tkinterdnd2/TkinterDnD.py", line 53, in _require
_tkinter.TclError: can't find package tkdnd
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 16, in <module>
File "tkinterdnd2/TkinterDnD.py", line 285, in __init__
File "tkinterdnd2/TkinterDnD.py", line 55, in _require
RuntimeError: Unable to load tkdnd library.
[7015] Failed to execute script 'main' due to unhandled exception!
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
我在互联网上尝试寻找答案,但它们要么对我不起作用,要么不够清楚,如下所示:*.py 带有 tkinterdnd2 模块的脚本不会编译为可执行文件(这个解决方案仍然给了我同样的错误)。
我还尝试过使用其他模块来打包,例如 cx_freeze 和 py2app,但两者都产生了不同的错误,所以我现在回到 pyinstaller。我在 macOS 上。
有什么办法可以修复这个错误吗?
编辑
也尝试了
python -m PyInstaller --clean -y -n "output_name" --add-data="tkdnd:tkdnd" main.py
,但运行时产生了同样的错误。
PyInstaller
网站中有关于
tkinterdnd2
的部分。
基本上所需的步骤是:
hook-tkinterdnd2.py
从网站复制到您的项目文件夹或使用以下内容创建该文件:from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('tkinterdnd2')
PyInstaller
如下:pyinstaller -F main.py --additional-hooks-dir=.
或者根据您问题中的命令:
python -m PyInstaller -F main.py --additional-hooks-dir=.
我终于在没有手动移动文件夹的情况下让它工作了。
pip install tkinterdnd2
我使用 auto py 来执行,它不能与“--add-binary”一起使用,所以我在 GUI 中使用“add-folder”,这基本上只是“--add-data”。
pyinstaller --noconfirm --onefile --windowed --add-data "<python_path>/Lib/site-packages/tkinterdnd2;tkinterdnd2/" "<your_script>"
这里的问题是拖放需要两个组件:TCL 库和它们的 Tkinter 接口。我手动安装两者来配置我的环境。 (请参阅我对How to Install and Use TkDnD with Python Tkinter on OSX?的回答)。我知道有人在 PyPI 上为 TkinterDnD2 打包了一些东西,但我还没有研究过。
我有一个使用 TkinterDnD2 的项目。我用 PyInstaller 构建它并看到与您看到的相同的错误(或多或少)。使用 --onedir 选项(而不是 --onefile 选项)运行 PyInstaller,我发现我的
tkdnd2.8
目录中缺少 dist
。
为了纠正这个问题,我在 Windows 上添加了
--add-binary "C:/Python/Python38-32/tcl/tkdnd2.8;tkdnd2.8"
到 PyInstaller 命令行,就成功了。我现在可以构建一个 --onefile 可执行文件,并且它运行时没有错误。
您尝试了类似的方法,但我使用了 --add-binary 而不是 --add-data,并且我给出了库的完整路径。
我不确定其他答案的第一手经验,但我个人在我的应用程序中分发 tkdnd。当然,我是在 PyPi 中提供
tkinterdnd2
之前首先这样做的。我使用了 tkdnd 发行版和 python 包装器。
在我的构建脚本中,我有
copy_tree('build_files/tkdnd2.9.2', os.path.dirname(sys.executable) + '/tcl/tkdnd2.9.2')
copy_tree('build_files/TkinterDnD2', os.path.dirname(sys.executable) + '/Lib/site-packages/TkinterDnD2')
在我的规格文件中,
tkdnd = [(os.path.abspath(file), 'tkdnd2.9.2') for file in iglob('build_files/tkdnd2.9.2/*.*')]
data_files = [...] + tkdnd
a = Analysis9(..., datas=data_files,...)
你可以进一步看看我的项目,Music Caster
就我而言,以下方法有效(感谢哈米特)。我只是想发布此内容,因为在 Windows 11 上,我发现 tkinterdnd2 包文件的路径略有不同,至少在我的情况下是如此。
pyinstaller --onefile --add-data "[path-to-python]\Lib\site-packages\TkinterDnD2\tkdnd\win64;TkinterDnD2" "[my-script-name].py"
另外,我必须将包名称本身大写 - 我想它必须与脚本顶部的 import 语句中的包名称相同? “从 TkinterDnD2 导入 *”