我正在使用 PySide6 和 pygraphviz 创建一个简单的三个小部件桌面应用程序。当我使用
pyinstaller --onefile --noconsole stackedAPP.py
时,PyInstaller 向我抛出此错误: Unable to find '/usr/sbin/neato' when adding binary and data files.
似乎 PyInstaller 找不到任何 pygraphviz 布局,而不仅仅是 neato,因为我也尝试使用其他布局。这不是一个孤立的问题,正如我在这篇旧文章中发现的那样,但没有答案,所以我不得不再次询问。
修改包的钩子后,类似的 PyInstaller 错误here似乎已得到解决,因此我尝试查看 hook-pygraphviz.py。
在我看来,错误在于行:graphviz_bindir = os.path.dirname(os.path.realpath(shutil.which("dot")))
,它返回
/usr/sbin
经过进一步调查,我发现shutil.which('dot')
返回
/usr/bin/dot
,这实际上是正确的(已手动确认)。但 os.path.realpath('/usr/bin/dot')
的结果实际上完全是另一回事:>>> import os
>>> import shutil
>>> shutil.which("dot")
'/usr/bin/dot'
>>> os.path.realpath('/usr/bin/dot')
'/usr/sbin/libgvc6-config-update'
所以 PyInstaller 在 /usr/sbin 中找不到 neato 的原因是因为它不在 /usr/sbin 中,这就是它首先在 /usr/sbin 中搜索的原因。 所以我决定手动修改hook,将路径设置为
graphviz_bindir = '/usr/bin'
这有助于 PyInstaller 成功编译,但是当我使用该应用程序时,它在进入使用 pygraphviz 的阶段时崩溃,这是我看到的错误消息:
(stackedAPP:18070): GLib-GIO-CRITICAL **: 22:02:47.490: GFileInfo created without standard::icon
(stackedAPP:18070): GLib-GIO-CRITICAL **: 22:02:47.490: file ../../../gio/gfileinfo.c: line 1766 (g_file_info_get_icon): should not be reached
Traceback (most recent call last):
File "processUI.py", line 127, in on_finished
File "processUI.py", line 189, in generate_causal_loop_diagram
File "pygraphviz/agraph.py", line 1613, in draw
File "pygraphviz/agraph.py", line 1404, in _run_prog
OSError: Warning: Could not load "/tmp/_MEIsRtebz/graphviz/libgvplugin_pango.so.6" - file not found
Warning: Could not load "/tmp/_MEIsRtebz/graphviz/libgvplugin_pango.so.6" - file not found
Warning: Could not load "/tmp/_MEIsRtebz/graphviz/libgvplugin_pango.so.6" - file not found
Warning: Could not load "/tmp/_MEIsRtebz/graphviz/libgvplugin_pango.so.6" - file not found
Warning: Could not load "/tmp/_MEIsRtebz/graphviz/libgvplugin_gd.so.6" - file not found
Format: "png" not recognized. Use one of: bmp canon cmap cmapx cmapx_np dot dot_json eps fig gd gd2 gif gtk gv ico imap imap_np ismap jpe jpeg jpg json json0 mp pdf pic plain plain-ext png pov ps ps2 svg svgz tif tiff tk vdx vml vmlz vrml wbmp webp x11 xdot xdot1.2 xdot1.4 xdot_json xlib
我不知道如何从这里继续。我正在使用 VirtualBox 来运行 Ubuntu-23.10,并在其上运行此进程。当我安装 graphviz 和 pygraphviz 时,我使用了:
sudo apt-get graphviz graphviz-dev
pip install pygraphviz
按照本文档
cxfreeze -c translator.py --target-dir dist
并得到了一个运行没有任何错误的应用程序。我得看看 cx_Freeze 的做法与 PyInstaller 有何不同。
也可以使用pyinstaller,但我必须稍微修改hooks/stdhooks/hook-pygraphviz.py
。我将
graphviz_bindir = os.path.dirname(os.path.realpath(shutil.which("dot")))
行修改为 graphviz_bindir = shutil.which('dot')
,并通过定位 graphviz 所在位置然后使用 pyinstaller 中的 --add-binary 参数添加动态 graphviz 库。对我来说,这就像pyinstaller --onefile --add-binary /usr/lib/x86_64-linux-gnu/graphviz:graphviz main.py
。