PyInstalled Kivy 应用程序无法在第二台机器上运行
问题描述
我正在使用 PyInstaller (3.4) 打包一个 Kivy 应用程序,以便在 Windows 机器上使用.我已经让它在我的机器上编译和工作,但是当将 exe 移动到另一个时,它无法给出错误:
I'm packaging a Kivy app using PyInstaller (3.4) for use on Windows machines. I've gotten it to compile and work on my machine but when moving the exe to another, it fails giving the error:
[WARNING] [Image ] Unable to load image
C:Users<OTHER_MACHINES_USER>AppDataLocalTemp_MEI38442kivy_installdataglsldefault.png>
[CRITICAL] [Window ] Unable to find any valuable Window provider.
sdl2 - Exception: SDL2: Unable to load image
当整个东西被复制时(如在 ./dist/client_iface.exe
中),这在 dist
文件夹中起作用,所以我认为这是一个依赖问题我'一直无法解决,显然是使用 SDL2.
This works from the dist
folder when the whole thing is copied across (as in ./dist/client_iface.exe
) and so I figure its a dependency issue I've been unable to resolve, apparently with SDL2.
我相信这个问题与 几乎相同这个问题 但是这个问题已经存在两年了,至今还没有成功的解决方案.
I believe that this problem is almost identical to this problem however that question is two years old and as yet has no successful solution.
我遵循了许多指南(包括 这个 从上面的帖子链接)但没有成功.
I've followed a number of guides (including this one which is linked from the above post) but with no success.
规范文件,根据 Kivy 指南进行了调整, 如下:
The spec file, with adjustments as per the Kivy guide, is as follows:
# -*- mode: python -*-
from kivy.deps import sdl2, glew
import os
block_cipher = None
a = Analysis(
['client_iface.py'],
pathex=['D:\Users\<USER>\Documents\2_Projects\py_dice_roller\client'],
binaries=[('D:\Users\<USER>\Documents\2_Projects\DnD\py_dice_roller\client\SDL2.dll', '.')],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False
)
a.datas += [
('client_iface.kv', '.\client_iface.kv', 'DATA'),
('active.png', '.\images\active.png', 'DATA'),
('back.png', '.\images\active.png', 'DATA'),
('normal.png', '.\images\active.png', 'DATA'),
('DroidSansMono.ttf', '.\fonts\DroidSansMono.ttf', 'DATA')
]
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher
)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='client_iface',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True,
icon='.imagesicon_dWU_icon.ico',
)
coll = COLLECT(
exe, Tree(os.getcwd()),
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
strip=False,
upx=True,
name='client_iface'
)
按照上面的链接,我在脚本中包含了以下代码:
And following the above linked I have included the following code in the script:
def resourcePath(path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS)
return os.path.join(os.path.abspath(path))
if __name__ == '__main__':
kivy.resources.resource_add_path(resourcePath('.'))
kivy.resources.resource_add_path(resourcePath('./images'))
main_app().run()
我使用的命令是:
python -m PyInstaller -F --onefile .client_iface.spec
预期结果是生成的单个可执行文件可以在任何类似机器上运行而不会出错或不需要整个文件夹的附加文件.
The expected result would be that the single executable produced would run on any like-machine without error-ing or the need for the entire folder of additional files.
任何帮助将不胜感激.
解决方案
.spec
文件的 COLLECT
部分表示 onedir
将创建可执行文件.为了使 onefile
可执行,您需要删除 COLLECT
部分.此外,COLLECT
部分中列出的 sdl2 和 glew deps 可以作为 *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)]
代替出现在第一个关键字参数之前的默认 [],
.
The COLLECT
section of your .spec
file indicates that a onedir
executable will be created. In order to make a onefile
executable, you will need to remove the COLLECT
section. Also, the sdl2 and glew deps that are listed in the COLLECT
section can be added to the EXE
section as *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)]
in place of the default [],
that appears before the first keyword argument.
另外,请注意,如果您使用的是 .spec
文件,则 Pyinstaller
的大多数命令行选项都会被忽略.有关详细信息,请参阅 文档.不幸的是,Pyinstaller
文档在很多地方都相当模糊.
Also, note that most of the command line options of Pyinstaller
are ignored if you are using a .spec
file. Refer to the documentation for more details. Unfortunately, the Pyinstaller
documentation is rather vague in many places.
相关文章