【问题标题】:PyInstalled Kivy App Fails to Run on Second MachinePyInstalled Kivy 应用程序无法在第二台机器上运行
【发布时间】:2019-01-11 21:36:47
【问题描述】:

我正在使用 PyInstaller (3.4) 打包一个 Kivy 应用程序,以便在 Windows 机器上使用。我已经让它在我的机器上编译和工作,但是当将 exe 移动到另一个时,它无法给出错误:

[WARNING] [Image       ] Unable to load image 
C:\Users\<OTHER_MACHINES_USER>\AppData\Local\Temp_MEI38442\kivy_install\data\glsl\default.png>
[CRITICAL] [Window      ] Unable to find any valuable Window provider.
sdl2 - Exception: SDL2: Unable to load image

当整个内容被复制时(如./dist/client_iface.exe),这在dist 文件夹中有效,所以我认为这是一个我无法解决的依赖问题,显然是使用 SDL2。

我相信这个问题与this problem 几乎相同,但是这个问题已经存在两年了,至今还没有成功的解决方案。

我遵循了许多指南(包括从上述帖子链接的this one),但没有成功。

按照the Kivy guide调整的spec文件如下:

# -*- 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='.\images\icon_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'
)

按照上面的链接,我在脚本中包含了以下代码:


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

预期结果是生成的单个可执行文件可以在任何类似机器上运行而不会出错或不需要整个文件夹的附加文件。

任何帮助将不胜感激。

【问题讨论】:

  • Pyinstaller 不明显的一点是,当使用spec 文件时,大多数命令行选项都会被忽略。请参阅documentation。特别是,-F--onefile 将被忽略。
  • John,我现在在EXE 的选项部分中得到了[('onefile', None, 'OPTION')](和F),但不幸的是结果没有变化。不过感谢您的提示。
  • .spec 文件中EXE 部分的options 是在运行.exe 结果时传递给python 解释器的选项。这些选项不是Pyinstaller 选项。
  • 尝试删除Pyinstaller 创建的dist 目录,然后再次运行Pinstaller。如果生成的dist 文件夹只有一个exe 文件,那么您的.spec 文件设置为创建一个onefile 可执行文件。如果dist 文件夹中还有其他内容,则您的.spec 文件设置为创建onedir 可执行文件,并且该文件夹中的exe 文件在没有整个文件夹的情况下将无法工作。
  • 好的,我将如何在.spec 中设置onefile 以影响PyInstaller 而不是Python 解释器。文档中对onefile 的唯一引用与OSX(不是Windows)有关吗?我在任何地方都找不到对此选项的引用。

标签: python kivy sdl pyinstaller


【解决方案1】:

.spec 文件的COLLECT 部分表示将创建一个onedir 可执行文件。为了使onefile 可执行,您需要删除COLLECT 部分。此外,COLLECT 部分中列出的 sdl2 和 glew deps 可以作为 *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)] 添加到 EXE 部分,代替出现在第一个关键字参数之前的默认 [],

另外,请注意,如果您使用的是.spec 文件,Pyinstaller 的大部分命令行选项都会被忽略。有关详细信息,请参阅documentation。不幸的是,Pyinstaller 文档在很多地方都相当模糊。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 2021-07-10
    • 1970-01-01
    相关资源
    最近更新 更多