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

问题描述

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

I've got a very simple App (just a window with a label) and I am trying to walk myself through the process of turning into a single executable. Here is the program directory:

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 甚至 PyInstaller docs 但未能成功编译为单个可执行文件.这是 prog_test.spec:

I've successfully used PyInstaller to compile the program to an executable, but only using the one folder bundle method described in their docs; I'm looking to use the one file bundle method instead. So far, when I compile, the App launches but its a black screen (traditionally I have seen this when the main.kv cannot be loaded). I've read this, this, this and even the PyInstaller docs but have had no luck in successfully compiling to a single executable. Here is the 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 个索引.我的命令顺序如下:

I'm curious if it is the a.datas appending method causing problems, since all the examples have 3 indices while the documentation only has 2 indices. My command sequence is the following:

# 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)文件方面做错了什么?

What am I doing incorrectly to include the support (.kv, .json) files?


解决方案

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

I was also having this problem with a very simple example and had also read the same articles that you mentioned. Similarly, my app worked when bundled in a folder but not in a single exe file. I moved the kivy app class to a separate .py file so the main file looked something like this:

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目录.

The myapp.kv was added in the spec file as data. And this worked for me. My suspicion is that the kivy resource path first needs to add the meipass directory before importing any other kivy packages in the python script.

相关文章