PyInstalled Kivy 应用程序无法在第二台机器上运行

2022-01-15 00:00:00 python kivy pyinstaller sdl

问题描述

我正在使用 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.

相关文章