Compiling Python code with an image and sounds folder? - python

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

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.

Related

python3 images in imported modules

I am writing a program in Python 3.10 on a W11 machine to do things with a large collection of images. The images are divided into categories. Each category is treated slightly differently and there is a front end menu to select the category and import the relevant module. Each module is written as a stand alone .py file. My problem is that although the modules run well as stand alone files, when imported I get an error "tkinter.TclError: image "pyimage1" doesn't exist". Two bits of hopefully minimum reproducible examples are included; Universal Viewer test.py which is the menu script and Art_Viewer_test which is imported as a module. Pointers to the error would be appreciated.
MENU CODE
'''
from tkinter import *
import sys
root = Tk()
root.attributes("-fullscreen", True)
root.configure(bg="black")
def q_key_pressed(event):
if root.attributes("-fullscreen")==False:
root.attributes("-fullscreen", True)
else:
root.attributes("-fullscreen", False)
sys.exit()
def act_on_selection(x):
if x==1:
import Art_Viewer_test
opening_menu_frame=Frame(root,bg="black",relief='flat',bd=0, highlightthickness=0)
text_for_heading='\n\n\n\n\n\n\nIMAGE VIEWER\n\n\n'
heading=Label(opening_menu_frame,bg='black',fg='lightgray',font=
("Arial","16"),text=text_for_heading,bd=0)
heading.pack()
art = Button(opening_menu_frame,pady=15,borderwidth=0,text="Art Images",font=
("Arial","16"),bg='black',fg='white',command=lambda:
act_on_selection(1))
art.pack()
inst_text='\n\n\n\n\n\n\nClick one of the catagories or Q to exit the program'
instruction=Button(opening_menu_frame,borderwidth=0,text=inst_text,font=
("Arial","16"),bg='black',fg='white')
instruction.pack()
opening_menu_frame.pack()
root.bind("q",q_key_pressed) and root.bind("Q",q_key_pressed)
root.mainloop()'''
MODULE CODE
'''
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
def right_key_pressed():
#do stuff
pass
control_frame=Frame(root,bg="lavender",relief='flat', borderwidth=40)
control_frame.pack()
image=Image.open("icons/next.gif")
nexticon = ImageTk.PhotoImage(image)
nextimageclick=Button(control_frame,image=nexticon, text
="next",compound="bottom",command=right_key_pressed)
nextimageclick.pack()
root.mainloop()
'''

Python exe cannot identify image file

I'm making a Tkinter application and created an executable of my project containing the main.py file and 2 other helper .py files located in "path/to/python/project/folder" using Pyinstaller:
pyinstaller --exclude-module PyQt5 --onefile -p "path/to/python/project/folder" main.py
At some point in the main.py file an image is selected by the user from their system and then shown in the GUI. To do so I create image.jpg in "path/to/python/project/folder". When running my code in an IDE things work fine but when I run main.exe I get the following error: OSError: cannot identify image file 'image.jpg'
There's also an empty image created in the same folder as where the .exe file is located.
Is there a way to make the .exe file behave like the original python 'project'? Or can one simply not create new files and access them from an .exe file?
EDIT: the user selects a video and the application shows the middel frame as an image that’s why a new image is created.
EDIT: here's some code to maybe clarify some things:
import tkinter as tk
from tkinter import filedialog, messagebox, simpledialog
import cv2
from PIL import Image, ImageTk
import os
fpsGlobal = -1
class GUI:
def __init__(self, master):
self.master = master
self.master.title("TITLE")
self.readyForAnalysis = False
self.workdir = os.getcwd()
self.data = None
self.fps = fpsGlobal
self.finished = False
self.frame = tk.Frame(master)
self.frame.pack()
self.menu = tk.Menu(self.frame)
self.file_expand = tk.Menu(self.menu, tearoff=0)
self.file_expand.add_command(label='Open...',command=self.openVideo)
self.menu.add_cascade(label='File', menu=self.file_expand)
self.master.config(menu=self.menu)
def openVideo(self):
'''Opens the video when open... button is clicked and shows a screenshot of a frame from the video'''
self.filename = filedialog.askopenfilename(initialdir = '/', title = 'Select file', filetypes = (("avi files",".avi"),("all files","*.*")))
# if a video is loaded and openfiledialog is not cancelled
if self.filename:
# read videofile
cap = cv2.VideoCapture(self.filename)
self.totalFrames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
global fpsGlobal
fpsGlobal = int(cap.get(cv2.CAP_PROP_FPS))
cap.set(cv2.CAP_PROP_POS_FRAMES, int(self.totalFrames/2))
ret,frame = cap.read()
cv2.imwrite("image.jpg", frame)
# show image
image = Image.open("image.jpg")
#print("image.size = (%d, %d)" % image.size)
resizedImg = image.resize((704, 576), Image.ANTIALIAS)
picture = ImageTk.PhotoImage(resizedImg)
self.label = tk.Label(self.frame,image=picture)
self.label.image = picture
self.label.pack()
cap.release()
cv2.destroyAllWindows()
try:
os.remove("image.jpg")
except: print("no")
self.readyForAnalysis = True
self.analyzeButton.configure(background='green2')
self.welcome.config(text="Start the analysis of the video by clicking the 'Analyze' button." )
def main():
root = tk.Tk()
root.geometry('1000x750')
my_gui = GUI(root)
root.mainloop()
if __name__== "__main__":
main()
So in the GUI the user is able to select a video file which later will be analyzed. To provide some feedback to the user i'll show the middle frame of the video as an image within the GUI. When running the code in my IDE everything works but running it from the .exe file I get an error (see error above) at line image = Image.open("image.jpg")
I believe I may have found the solution to my own question. It is not possible to create files in an executable the same way as in a Python project folder and access them afterwards since there's no folder structure in the .exe file.
The way this probably can be solved is by using the tempfile library.

Create a single tkinter GUI to run any python script by defining the path

I am interested to create a single tkinter GUI in which i can define a path to run a python script located in a particular folder. The code is shown below. It can read the required .py file from the set of files in that folder using the path i have given and open the dialogue box for plot graphs too but doesnt do anything. When i click the plot graphs button rather it gives an error "AttributeError: 'int' object has no attribute 'display_graph'". Can anyone check and edit my code to help.(I am using spyder so tk is tkr). I know about py2exe, So i would appreciate if someone can help with tkinter GUI code. Thanks
My python script is Empdata.py and i used def display_graph(data) in it:
Code
import glob
import tkinter as tkr
import os
path = r'C:\Users\C253271\Desktop\Empower data\\'
allpyfiles =glob.glob(os.path.join(path, "*.py"))
for file in allpyfiles:
file =('Empdata')
def graph():
global v
file.display_graph(v.get())
root = tkr.Tk()
v = tkr.StringVar()
tkr.Button(root, text='Close',command=root.destroy).grid(row=2, column=1)
tkr.Button(root, text='Plot Graphs', command = graph).grid(row=2, column=0)
root.mainloop()
In the code from the question, file is a string. It thus does not have any methods. What you really want to do is to import the python file, such that its content is available.
To do so, you may use importlib
f = importlib.import_module("Empdata") # if you have Empdata.py in your folder
f.some_method()
Your example should therefore look something like
import Tkinter as tkr
import importlib
fn = "Empdata"
f = importlib.import_module(fn)
def graph():
global v
f.display_graph(v.get())
root = tkr.Tk()
v = tkr.StringVar()
tkr.Button(root, text='Close',command=root.destroy).grid(row=2, column=1)
tkr.Button(root, text='Plot Graphs', command = graph).grid(row=2, column=0)
root.mainloop()

How do I upload an image on Python using Tkinter?

I am doing GUI programming using Tkinter on Python. I am using the grid manager to make widgets. I have created several buttons and I want to upload an image on top of them. When I enter this code, it gives me an escape sequence error.
I heard using PIL is not a good idea? Is that true?
cookImage = PhotoImage(file = "image/C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
Windows filenames must be entered as raw strings:
cookImage = PhotoImage(file=r"C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
This applies to all of Python, not just PIL.
Use:
path = r"a string with the path of the photo"
Note the r prefix, it means a raw string.
...
img = ImageTk.PhotoImage(Image.open(file=path))
label = tk.Label(root, image = img)
label.something() #pack/grid/place
...
The path can be:
Absolute ("C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
Relative ("\cook.gif", depends on where the Python code is)
If you have an image file that is exactly what you want, just open it with BitmapImage or PhotoImage. Note that Tcl/Tk 8.6, which you should have with 3.6 on Windows, also reads .png files. On Windows, prefix the filename with 'r' or use forward slashes: 'C:/User/...'.
The actual PIL package is no longer maintained and only works on 2.x. That is what a new user should not use. The compatible successor, pillow (installed for instance with python -m pip install pillow) is actively maintained and works with 3.x. The compatibility extends to the import statement: import PIL imports pillow. Pillows allows one to manipulate images and to convert many formats to tk format (the ImageTk class).
this is exact code which is most help for move image
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import os, shutil
class Root(Tk):
def __init__(self):
super(Root,self).__init__()
self.title("thinter Dialog Widget")
self.minsize(640,400)
self.labelFrame = ttk.LabelFrame(self,text="Open A File")
self.labelFrame.grid(column=0,row=1,padx= 20, pady= 20)
self.btton()
def btton(self):
self.button = ttk.Button(self.labelFrame, text="Browse Afile", command=self.fileDailog)
self.button.grid(column=1,row=1)
def fileDailog(self):
self.fileName = filedialog.askopenfilename(initialdir = "/", title="Select A File",filetype=(("jpeg","*.jpg"),("png","*.png")))
self.label = ttk.Label(self.labelFrame, text="")
self.label.grid(column =1,row = 2)
self.label.configure(text = self.fileName)
os.chdir('e:\\')
os.system('mkdir BACKUP')
shutil.move(self.fileName,'e:\\')
if __name__ == '__main__':
root = Root()
root.mainloop()
you could not move image to c drive due to Permission denied: this code work successfully on python 3.8, 3,7

How can I set a tkinter app icon with a URL?

If I have:
from Tkinter import *
app = Tk()
...
app.mainloop()
Would I use app.iconbitmap(...)?
And if so, how would I go about using this as the file, and should I import urllib?
You can use this too replace the Tkinter default icon.
import base64, PIL, urllib, Tkinter
from Tkinter import *
from PIL import ImageTk
from urllib import *
root = Tk()
raw_data = urllib.urlopen("http://dl.dropboxusercontent.com/s/qtlincxkbbiz1qv/stat.gif").read()
b64_data = base64.encodestring(raw_data)
image = PhotoImage(data=b64_data)
root.tk.call('wm', 'iconphoto', root._w, image)
root.mainloop()
And then change the .py file extension to .pyw to change the taskbar icon.
The .pyw extension tells it to run with pythonw.exe instead of python.exe, but running with pythonw.exe also makes it run without the console.
So, you'll either have to run without the icon, or without the console.
This is the call that worked for me on both Windows and Linux. I found that I cannot use ico files on Linux, so only using gif files which works on both platforms.
class Editor(tk.Tk):
. . .
. . .
self.tk.call('wm', 'iconphoto', self._w, tk.PhotoImage(file = "my_icon.gif"))

Categories

Resources