简体   繁体   中英

Bundle data for pyinstaller error (--onefile)

I want to include an image for my.exe. I'm following the directions as listed here . It says the build completes successfully in terminal. When I run the.exe it marks a fatal error in the program.

Any ideas appreciated.

My directory looks like

/Box Tracking
--/res
----amazon_box.jpg
--main.py
--gui.py

Related code from gui.py:

import tkinter as tk
import main
import traceback
import time
import random
# use these libs since base tkinter can only open gif and other obscure formats
# must install Pillow rather than PIL
from PIL import ImageTk, Image
from jokes import jokes
import sys, os # these will allow me to bundle the image in the distro

def resource_path(relative_path):
    '''
    See notes
    :param relative_path: path I will use | string | 'res/amazon-box.jpg'
    :return: string | path
    '''
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)

root = tk.Tk()  # create GUI instance
root.geometry("1000x1000") # make GUI big so that users can see it
root.title('Box Tracking') # name GUI

# add a background so users can see it
bg_image = Image.open(resource_path('res/amazon-box.jpg'))
tk_bg_image = ImageTk.PhotoImage(bg_image)
bg = tk.Label(root,image=tk_bg_image)
bg.place(x=0,y=0,relwidth=1,relheight=1)

Snippet I use to build the.exe: pyinstaller --onefile --windowed --add-data res/amazon-box.jpg;. --name "Box Tracking 3.1.5" gui.py pyinstaller --onefile --windowed --add-data res/amazon-box.jpg;. --name "Box Tracking 3.1.5" gui.py

There may be a better way, but I do it this way:

In the \res\ directory I'd have amazon_box.py and an empty __init__.py

You can convert an image to a base64 using a small script such as:

import base64
with open("amazon_box.jpg", "rb") as image:
    b = base64.b64encode(image.read())
with open("amazon_box.py", "w") as write_file:
    write_file.write("def photo(): return (" + str(b) + ")"

in amazon_box.py it will have (automatically created by the above script):

def photo(): return (image_as_base64)

After that the image can be used in the main script with PhotoImage(data = ) :

import tkinter as tk
from res import amazon_box

root = tk.Tk()  # create GUI instance

root.geometry("1000x1000") # make GUI big so that users can see it
root.title('Box Tracking') # name GUI

# add a background so users can see it
tk_bg_image = tk.PhotoImage(data = amazon_box.photo())
bg = tk.Label(root,image=tk_bg_image)
bg.place(x=0,y=0,relwidth=1,relheight=1)

Obviously I haven't tested it with your image, but this is how I've wrapped images into onefiles in the past, and you can have multiple images in the one .py file, so it actually can be a pretty clean end result.

Edit:

Since it's just another module to PyInstaller at this point, my build command is the standard: pyinstaller.exe --windowed --onefile "path\to\main\py\file"

I usually just run PyInstaller from command prompt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM