1

I am currently working on a project, and in the end I'd need to compile it. The issue that I am facing is that I am working with the .py file, but also 2 folders, one with all of the images, and one with all of the music...

I've looked around, but nothing answers the questions completely. I've seen that it was best to base64 encode my images, but that didn't seem to work for me... I tried UTF-8 characters and binary.

Any idea on how I could transform my 2 folders and my code file into a single .exe executable, that can be used on any computer?

Thanks

Angaros

Angaros
  • 23
  • 2
  • Does this answer your question? [How to compile all resources into one executable file?](https://stackoverflow.com/questions/6689410/how-to-compile-all-resources-into-one-executable-file) – Jacques Gaudin Feb 12 '20 at 17:36

1 Answers1

1

Have you tried this kind of approach:


Let's assume you have some kind of layout like this

main.py
resources.py
data/img1.png

And in main.py:

import resources
import tkinter as tk

root = tk.Tk()
root.title("Test")

resources.load_images()
lbl = tk.Label(root, image=resources.IMG1)
lbl.place(relx=0.5, rely=0.5, anchor="c")

root.mainloop()

And in resources.py:

import tkinter as tk

IMG1 = None

def load_images():
    global IMG1

    IMG1 = tk.PhotoImage("data\\img1.png")

This works quite nicely, and can load your image.


Now let's make it work in one single exe file:

We don't need to change main.py, as it simply loads resources through our resources.py script.

We can load/save our image data using this script:

import base64

def load_data(filename):
    with open(filename, mode="rb") as f:
        return base64.b64encode(f.read())

print(str(load_data("data\\img1.png"), "utf-8"))
# R0lGOD ...

So we can now copy and paste this into our resources.py file, and change it to look like this:

import tkinter as tk

# here's our copied base64 stuff:
img1_data = '''
    R0lGODlhEAAQALMAAAAAAP//AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAA\nAAAAACH5BAEAAAIALAAAAAAQABAAQAQ3UMgpAKC4hm13uJnWgR
    TgceZJllw4pd2Xpagq0WfeYrD7\n2i5Yb+aJyVhFHAmnazE/z4tlSq0KIgA7\n
    '''

IMG1 = None

def load_images():
    global IMG1

    IMG1 = tk.PhotoImage(data=img1_data)

And now compile our main.py file using PyInstaller:

pyinstaller main.py --onefile

And we should see, once the task is complete, that there is a single executable file in dist, called main.exe.

Ed Ward
  • 2,333
  • 2
  • 10
  • 16
  • This is where I get an issue... My base64 code is 643 745 characters long... As such, it just makes IDLE crash... Is there maybe a way we can have a shortened code, or maybe there is another method to cramp all of the data into a single .exe file? I was also exploring the use of online folders to which my main program connects to and fetches the data from there. I haven't found anything conclusive, but maybe you know something that could work out? Thanks again! – Angaros Feb 12 '20 at 19:20
  • Could you write a python script to create the file that stores your code? – Ed Ward Feb 12 '20 at 19:28
  • Well, my code is 1020 lines long, so it might take you some time to read through it all... Basically, what I currently have is one folder, in which I have my python project, a .wav sound, images (~50), and lastly a .dat file that is uses my save games (using pickle library), also, don't worry, what you did has helped me. What I am trying to do is compile everything in the folder in a single .exe file, so the user can't mess around with single items like save games, and just receives an EXE. I need the images to be displayed to the user (using tkinter) from the images previously in the folder. – Angaros Feb 12 '20 at 21:27