Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include .kv/.json files while packaing kivy with PyInstaller --onefile?

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)

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)

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

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

like image 260
pstatix Avatar asked Jan 26 '18 19:01

pstatix


1 Answers

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

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.

like image 53
changp89 Avatar answered Nov 08 '22 08:11

changp89