PyInstalled Kivy App Fails to Run on Second Machine

落花浮王杯 提交于 2019-12-13 03:58:10

问题


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>\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

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.

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='.\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'
)

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()

And my command in use is:

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.

Any help would be appreciated.


回答1:


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.

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.



来源:https://stackoverflow.com/questions/54154373/pyinstalled-kivy-app-fails-to-run-on-second-machine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!