在使用 PyInstaller --onefile 打包 kivy 时包含 .kv/.json 文件?

Posted

技术标签:

【中文标题】在使用 PyInstaller --onefile 打包 kivy 时包含 .kv/.json 文件?【英文标题】:Include .kv/.json files while packaing kivy with PyInstaller --onefile? 【发布时间】:2018-07-06 04:19:45 【问题描述】:

我有一个非常简单的应用程序(只是一个带有标签的窗口),我正在尝试自己完成变成单个可执行文件的过程。这是程序目录:

brainfreeze/
   main.py # simple app
   main.kv # kv language style sheet
   config/
      settings.json # json settings panel data (F1 bound)
saving_to/
   (empty at start)

我已成功使用 PyInstaller 将程序编译为可执行文件,但仅使用他们的docs 中描述的一个文件夹捆绑方法;我希望改用一个文件捆绑方法。到目前为止,当我编译时,应用程序启动但它是一个黑屏(传统上我在无法加载 main.kv 时看到这个)。我已经阅读了this、this、this 甚至 PyInstaller docs,但没有成功编译为单个可执行文件。这是 prog_test.spec:

# -*- mode: python -*-

from kivy.deps import sdl2
from kivy.deps import glew

block_cipher = None

a = Analysis(['..\\brainfreeze\\main.py'],
             pathex=['H:\\TestBed\\single_exe_test'],
             binaries=[],
             data=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)

a.datas += [('../brainfreeze/main.kv', 'DATA'), ('../brainfreeze/config/settings.json', 'DATA')]

exe = EXE(pyz, Tree('../brainfreeze/'),
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
          name='prog_test',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True)

我很好奇是否是 a.datas 附加方法导致了问题,因为所有示例都有 3 个索引,而文档只有 2 个索引。我的命令顺序如下:

# from the 'saving to' directory
python -m PyInstaller --onefile --name prog_test ../brainfreeze/main.py
# alter the prog_test.spec to the above
python -m PyInstaller --onefile prog_test.spec

我在包含支持 (.kv, .json) 文件方面做错了什么?

【问题讨论】:

【参考方案1】:

我在一个非常简单的示例中也遇到了这个问题,并且还阅读了您提到的相同文章。同样,我的应用程序在捆绑在一个文件夹中而不是在单个 exe 文件中时可以工作。 我将 kivy 应用程序类移动到一个单独的 .py 文件中,所以主文件看起来像这样:

import os, sys
from kivy.resources import resource_add_path, resource_find
from myApp import AppClass

if __name__ == '__main__':
    if hasattr(sys, '_MEIPASS'):
        resource_add_path(os.path.join(sys._MEIPASS))

    app = AppClass()
    app.run()

myapp.kv 作为数据添加到规范文件中。这对我有用。 我的怀疑是kivy资源路径首先需要在python脚本中导入任何其他kivy包之前添加meipass目录。

【讨论】:

通过这种方法,我能够从命令行构建:pyinstaller --clean -F --add-data="myapp.kv:." myApp.py,而不用担心规范文件。

以上是关于在使用 PyInstaller --onefile 打包 kivy 时包含 .kv/.json 文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 PyInstaller 在 --onefile 中使用 QML 构建 PyQt5

在使用 PyInstaller --onefile 打包 kivy 时包含 .kv/.json 文件?

Pyinstaller --onefile 模式,如何在解包前向控制台写入消息

pyinstaller --onefile 生成0KB exe

如何将 PortAudio 包含到 pyinstaller onefile 构建中

使用 --onefile 和 --noconsole 使用 PyInstaller 编译的 PyQt5 应用程序,但 exe 无法启动