Bundle data for pyinstaller error (--onefile)

不想你离开。 提交于 2020-01-16 09:06:19

问题


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


回答1:


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.



来源:https://stackoverflow.com/questions/58630260/bundle-data-for-pyinstaller-error-onefile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!