Reputation: 73
I run the build command and everything appears to build correctly until I try to launch the exe and this message pops up:
Here is my spec file, I am not sure why it appears to be combing the file path with both images.
block_cipher = None
a = Analysis(['TripCalc.py'],
pathex=['C:\\Users\\test\\Downloads\\TripApp'],
binaries=[],
datas=[('C:\\Users\\test\\Downloads\\TripApp\\BennySM.ico', 'C:\\Users\\test\\Downloads\\TripApp\\BgSM.gif')],
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)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='TripCalc',
debug=False,
strip=False,
upx=True,
console=False ,
icon='C:\\Users\\test\\Downloads\\TripApp\\Benny.ico')
I tried adding the files beside datas:
('Benny.ico', 'C:\\Users\\test\\Downloads\\TripApp\\BennySM.ico', 'data', 'BgSM.gif', 'C:\\Users\\test\\Downloads\\TripApp\\BgSM.gif', 'data')
But it would not build with the ValueError: too many values to unpack (expected 2)
.
I followed the example from this post on how to add the file path to the main python file. Bundling data files with PyInstaller --onefile
I am able to build the exe and run it with the images commented out. Any help would be much appreciated.
When I get the Value Error message I setup the spec file with the following:
block_cipher = None
a = Analysis(['TripCalc.py'],
pathex=['C:\\Users\\test\\Downloads\\TripApp'],
binaries=[],
datas=[('Benny.ico','C:\\Users\\test\\Downloads\\TripApp\\BennySM.ico','data','BgSM.gif','C:\\Users\\test\\Downloads\\TripApp\\BgSM.gif','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)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='TripCalc',
debug=False,
strip=False,
upx=True,
console=False ,
icon='C:\\Users\\test\\Downloads\\TripApp\\Benny.ico')
Error window
With those changes to the spec file everything builds but the failed to launch script pops up when launching the exe. If they got packed with the exe they should be locationed in the temp file in app data correct?
Thanks!
Upvotes: 3
Views: 3018
Reputation: 2645
In order to get around this for my own packages - which I try to make pip-installable - I have created a package that I'm calling stringify
. The readme has the primary use case.
The idea of stringify
is that you build your images (and other files types as well) into .py
files which will be natively recognized by PyInstaller, requiring no _MEIPASS
or if sys.frozen
voodoo. Your spec files become more portable and are more likely to work out of the box.
Additionally, if you package your files up for distribution on pypi, then someone uses your images in their package, they don't have to do any spec file manipulation.... it just works!
Within setup.py
- or sometime before you distribute your package:
from stringify import stringify_py
stringify_py('images', 'my_package/images.py')
You can then import your images and replace your calls to tkinter.PhotoImage
like so:
from images import img
# tkinter.PhotoImage(file='/path/to/img.png') # <- your original call
tkinter.PhotoImage(data=img) # <- new call
For an example of this method, you might reference my tk_tools package. Have a look at setup.py
and in tk_tools/visual.py
. Note how the images are also stored within tk_tools/images.py
, which is imported and used directly. PyInstaller will pick these up directly with the 'standard' spec file, reducing your mind share at build-time.
Upvotes: 2
Reputation: 49784
From the (DOCS):
Adding Data Files:
To have data files included in the bundle, provide a list that describes the files as the value of the
datas=
argument toAnalysis
. The list of data files is a list oftuples
. Each tuple has two values, both of which must be strings: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.
So your datas
line will need to be something like:
datas=[
('C:\\Users\\test\\Downloads\\TripApp\\BennySM.ico', 'data'),
('C:\\Users\\test\\Downloads\\TripApp\\BgSM.gif', 'data'),
],
Upvotes: 4