Pyinstaller embed images folder in --onefile --windowed application

Viewed 1422

I am trying to embed a folder with images into generated (with PyInstaller) executable. But it doesn't work for me. Even with one simple image!

The datas variable in my main.spec file looks like this:

datas=[ ('C:\\Users\\<user>\\dir1\\dir2\\MyApp\\images\\*.png', 'images') ],

According to the documentation:

The first string specifies the file or files as they are in this system now. The second specifies the name of the folder to contain the files at run-time.

In the python file I read the image like this:

self.SetIcon(wx.Icon("images\\myicon.png"))

Finally, this is how I package everything in the *.exe using PyInstaller:

pyinstaller --onefile --windowed --icon=images\main32x32.ico main.spec

I am getting the following error:

Failed to load image from file "images\myicon.png"

Could someone tell me what I'm doing wrong?

1 Answers

When you want to embed a file into your executable, you need to do two steps:

First, add it with add-data to your executable (as you already did). Next, load the file from the extracted path on runtime.

Here you are trying to load the file from images/myicon.png, and the path is next to your executable. Still, the file is not there, and meanwhile, the runtime files would be extracted in a temp directory, e.g. C:/Users/<user>/AppData/Local/Temp/_MEIXXX. So it needs to be loaded from that directory.

You can use sys._MEIPASS to get the temp path where the extracted files are located. Moreover, you can create a function to load external files:

import os
import sys


def resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)


self.SetIcon(wx.Icon(resource_path("images/myicon.png")))
Related