KivyMD with PyInstaller hooks - Images not showing in the standalone .exe

420 views Asked by At

GOAL

I'm using kivymd with PyInstaller hooks in order to create the standalone .exe.

PROBLEM

Everything works fine in the standalone .exe except for the images that are not showing.

Please note that the images show up in the application executed from the script, but not in the standalone.

LOCATION OF THE IMAGES

Images are stored in a folder named 'media' and are linked with a relative path in the script. Please see the example below regarding "myicon.png" in the MDToolbar

MDToolbar:
    title: "My title"
    left_action_items: [['media\myicon.png', lambda x: None]]
    elevation: 10

FILE .SPEC

Following the documentation (this and this) for adding images/files in the standalone I created a spec file like this below:

# -*- mode: python ; coding: utf-8 -*-
import sys
import os
from kivy_deps import sdl2, glew
from kivymd import hooks_path as kivymd_hooks_path
path = os.path.abspath(".")


added_files = [                      

    ( 'media\myicon.png', 'media' ) # Single file
    # ( 'media/myicon.png', '.' ), # Single file
    # ( 'media/myicon.png', '.' ), # Single file
    # ( '/media/data', 'data' ), # Folder
    # ( '/media/*.png') # multiple files # prova mia
    # ( '/media/sfx/*.mp3', 'sfx' ) # multiple files

    # ( '.\\media\\myicon.png', 'media' )  # # hookspath='.\\hooks\\',
]


a = Analysis(
    ["main.py"],                              
    pathex=[path],
    hookspath=[kivymd_hooks_path],
    datas = added_files,     
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=None,
    noarchive=False,
)

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

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,             
    *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
    debug=False,
    strip=False,
    upx=True,
    name="myname",                       
    console=False,
    icon='myicon.ico'    
)

As you can see, in the "added_files" (list of tuples) I tried also other options (now commented out), but no one allows images to appear in the standalone.

At the moment I think that this issue might be related to one of two possibile issues:

  1. The syntax is wrong (e.g. 'media\myicon.png', 'media' )
  2. The logic related to the association of "added_files", "datas = added_files", "a.datas" is wrong.

Could yuo please help me to solve? thanks in advance

1

There are 1 answers

1
John Anderson On BEST ANSWER

In my experience, I have used the form:

added_files = [ ( 'media/myicon.png', 'media' ) # Single file]

Using forward slash.

And then at the top of my main.py I add:

if getattr(sys, 'frozen', False):
    # this is a Pyinstaller bundle
    kivy.resources.resource_add_path(sys._MEIPASS)
    kivy.resources.resource_add_path(os.path.join(sys._MEIPASS, 'media'))