Search code examples
pythonkivypackaging

Can't create a .exe with python kivy on windows (Pyinstaller)


So, I'm trying to make a .exe from a python kivy code, The .exe is made, but it doesn't open. No message, nothing. I'm checking the logs but theres no problem in there, so I'm completely in the dark here. I'm using the following .spec

# -*- mode: python -*-

block_cipher = None
from kivy_deps import sdl2, glew, gstreamer
spec_root = os.path.abspath(SPECPATH)
app_name = 'Gameficacao'

a = Analysis(['C:/Users/Artur/PycharmProjects/gameficacao/Gameficacao.py'],
             pathex=[spec_root],
             datas=[('C:/Users/Artur/PycharmProjects/gameficacao/*.kv', '.'), ('C:/Users/Artur/PycharmProjects/gameficacao/img/*.png', './img'),('C:/Users/Artur/PycharmProjects/gameficacao/font/*.ttf', './font'),('C:/Users/Artur/PycharmProjects/gameficacao/som/*.mp3', './som')],
             hiddenimports=['win32timezone'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name=app_name,
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=False,
          console=False)
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               *[Tree(p)
for p in (sdl2.dep_bins + glew.dep_bins +  gstreamer.dep_bins)],
               strip=False,
               upx=False,
               name=app_name)

If you guys have anything that can help me (ANYTHING), please let me know.


Solution

  • Ok so I figured it out. FIRST OF ALL, if you are having this problem, you will have to first add the following line to your code:

    def reset():
        import kivy.core.window as window
        from kivy.base import EventLoop
        if not EventLoop.event_listeners:
            from kivy.cache import Cache
            window.Window = window.core_select_lib('window', window.window_impl, True)
            Cache.print_usage()
            for cat in Cache._categories:
                Cache._objects[cat] = {}
    
    if __name__ == '__main__':
        reset()
        'your app name here'().run()
    

    That will prevent the app from not opening (like when it looks like its loading but nothing opens). AFTER THAT, you wanna build using the spec like this:

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    from kivy_deps import sdl2, glew, gstreamer
    
    
    a = Analysis(['C:\\Users\\Artur\\PycharmProjects\\gameficacao\\Gameficacao.py'],
                 pathex=['C:\\Users\\Artur\\Desktop\\Trabalho\\Gameficacao'],
                 binaries=[],
                 datas=[('C:/Users/Artur/PycharmProjects/gameficacao/*.kv', '.'), ('C:/Users/Artur/PycharmProjects/gameficacao/img/*.png', './img'),('C:/Users/Artur/PycharmProjects/gameficacao/font/*.ttf', './font'),('C:/Users/Artur/PycharmProjects/gameficacao/som/*.mp3', './som')],
                 hiddenimports=['pkg_resources.py2_warn','win32timezone','six','packaging','packaging.version','webbrowser','kivy','enchant'],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              [],
              exclude_binaries=True,
              name='Gameficacao',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              console=True )
    coll = COLLECT(exe,
                   a.binaries,
                   a.zipfiles,
                   a.datas,
                   *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins +  gstreamer.dep_bins)],
                   strip=False,
                   upx=True,
                   upx_exclude=[],
                   name='Gameficacao')
    

    Now, some things are VERY IMPORTANT here and the app probably won't run without it, and those are:

    1. The line "from kivy_deps import sdl2, glew, gstreamer", right on the top
    2. The filling of the data part of the Analysis, here you will have to indicate the path of every file you will use on your app, including the kivy file. Use mine as a example.
    3. The hiddenimports line, here you will point out every import that is relevant for your app and that PyInstaller is not able to do. For starters, you will probably want to put the 'pkg_resources.py2_warn', since PyInstaller can't import it properly and you will need it.
    4. The line "*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins + gstreamer.dep_bins)]," will be a complement from the imports done on the beggining of the code.

    That solved the problem for me.