I have a python program, and inside it are a lot of images linked specifically through a file path. I used pyinstaller to export the program and it worked on my computer, however when sending it to another computer - an error occurred. It said the resource could not be found. Is there any way to bundle the images into a single executable file?
Edit:
I did try this however it didn't work:
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
Edit:
I'm creating the application in tkinter.
Thanks.
I lost days on this, so I'm adding this answer as much for myself as anyone else. It combines many other SO answers into one 'simpler' example. This builds an 'All in One' windows .exe file.
First, create a build.py file for PyInstaller in the applications root directory. (Note : PyInstaller overwrites .spec files so avoid editing them). You will have to run the command multiple times after code edits, so it makes sense to create a reusable script. Here is an example which you need to customise:
import PyInstaller.__main__
PyInstaller.__main__.run([
'gui\main.py',
'--name=myappname', # Name for .exe
'--distpath=dist',
'--add-data=images/main.ico;./images', # Icon to replace tkinter feather
'--add-data=images/logo.png;./images', # An image used in the app
'--clean',
'--onefile',
'--windowed',
'--noconsole',
], )
Above I use ; because I'm creating an .exe for windows, use : for Linux and Mac.
Second : As mentioned above you need to include the resource_path function in your app:
import os
import sys
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
Third : Use this function with your images :
self.iconbitmap(resource_path("images/main.ico"))
Wrap other images used in your app such as a company logo used within the app :
path_to_image = os.path.join("images", "logo.png")
self.myImage = PhotoImage(file=(resource_path(path_to_image)))
This should now build a onefile .exe with the images bundled nicely inside, and work on other computers (at least with the same version of Windows you built the app on).