I have a simple GUI program I'm building with Tkinter. I want to have a bunch of buttons with app images on them that, when clicked, launch that app. The problem is, Python can't recognise the Skype.gif file.
Code:
from tkinter import *
import os
def open_skype():
os.system('open /Applications/Skype.app')
master = Tk()
photo = PhotoImage(file='/Users/michael/Desktop/Skype.gif')
but = Button(master, image=photo, command=open_skype)
objs = [but]
column = 1
for i in objs:
i.grid(column=column, row=1)
column += 1
mainloop()
Error message:
_tkinter.TclError: couldn't recognize data in image file "/Users/michael/Desktop/Skype.gif"
Your problem is most likely that the image is not in the correct place. TO ensure that it is, try entering your command line (Terminal for Macs), and typing in ls /Users/michael/Desktop/Skype.gif. If prints Skype.gif or /Users/michael/Desktop/Skype.gif, then the file is there, otherwise it is not.
The path starts at where the python file is located so if they're in the same folder just put photo = PhotoImage(file='Skype.gif')
Tkinter only recognize s PNG images or JPG images in some cases. If you have a gif image you can incorporate it by using another module called WxPython. How this works is that it uses Frame by frame images to display a video type image. Tkinter does not support this.
Make sure your image is in the format of PNG or JPG
Related
I am trying to make a program to display one single image (.png extension) at once but giving a button to the user to change the picture.
What I have done is:
Reading the Image from my directory with help of Pillow module
Appended it to a list
With a button I increase or decrease the index of the list.
(Note I have to read 600 images approx.)
Here's the code:
import os
from tkinter import *
from PIL import ImageTk,Image
import threading,time
#Define the tkinter instance
x=0
win= Tk()
dir_path= os.path.dirname(os.path.realpath(__file__))
print(dir_path)
l1=[]
#Define the size of the tkinter frame
win.geometry("700x400")
def start():
threading.Thread(target=bg).start()
win.after(5000,threading.Thread(target=fg).start())
#Define the function to start the thread
def bg():
print("bg")
for i in range(1,604):
a=Image.open(f"{dir_path}\\{i}.png")
a=a.resize((500,700), Image.ANTIALIAS)
b=ImageTk.PhotoImage(a)
l1.append(b)
print(b)
print(len(l1))
def fg():
def add():
global x
x+=1
img2=l1[x]
d.configure(image=img2)
d.image = img2
d.update()
global d
d=Label(win,image=l1[x])
d.pack()
Button(win,text="add",command=add).place(x=0,y=0)
label= Label(win)
label.pack(pady=20)
#Create button
b1= Button(win,text= "Start", command=start)
b1.pack(pady=20)
win.mainloop()
But the problem is that the Tkinter gets dead freeze and laggy to an extent that the GUI is not operable.
So my question is,
How to fix Tkinter dead Frezzes and if there is any way to read the images as fast as possible?
The freezes of Tkinter depends on reading speed of the interpreter, because:
continuously reading and Showing the pictures are a huge job for Python.
reading images using opencv or any other image processing module wont help as reading part can become faster, but showing the image in tkinter is done using python only, so rapid changes in Label will cause tkinter to crash.
Solution:
Switch to a different compiler based language for example c++.
this solution is specifically for a image slideshow,
The solution is to use selenium with python. You can specify the image location in driver.get(image_path) and it will open the image for you, and if you want to change the image with a button, then just rename all your images with the numbers and make a button to add +1 to the index.
I'm trying to simply add an image to a tkinter button. I tried everything:
import tkinter as tk
root = tk.Tk()
root.geometry('300x300+300+150')
photo = tk.PhotoImage('home.gif')
btn = tk.Button(root, image = photo, width = 100, height = 100)
btn.image = photo # even with this does not work
btn.pack()
root.mainloop()
I also tried with PIL setting the photo variable equal to ImageTk.PhotoImage(Image.open('home.gif')), I tried easly the open function, the absolute path of the photo (and yes, the photo is inside the same directory of my script), but anything works. The window just pop up with a big button, without image inside.
UPDATE:
I tried with other images, and I noticed that some images are shown while others no. This is because the images with transparent background cause a bug or a problem to tkinter... so, I do not know if there's a way to solve this. On google I find out that some people use canvas but I actually need the image to be inside the button so I do not know how to do.
Please change your code as below
photo = tk.PhotoImage(file='home.gif')
because i changed the above code and it worked....
I know this question has been asked quite often, but I still can't figure out what's the problem:
I'm trying to make a simple Tkinter window with 4 Buttons. Each one should have a background Image. When I try to set image=path+'image.png' I get this: _tkinter.TclError: image "C:/Users/.../image.png" doesn't exist. The strange thing is that when I copy the path from the message and paste it into the Explorer adress line it opens the image i want to have as background image.
Here's the necessary code:
import tkinter
global path
path = 'C:/Users/Michael Hofmann/.../kahoot'
root = tkinter.Tk()
Button_red = tkinter.Button(root, image=path+'/images/red_small.png', command= pressed('red'))
Thanks in advance!
The error is telling you an image object doesn't exist by that name, not that a file doesn't exist by that name. The image option requires an object of type tkinter.PhotoImage. You can't just give it a path to an image.
image = tkinter.PhotoImage(file=path+'/images/red_small.png')
Button_red = tkitner.Button(..., image=image)
I'm currently working as an undergrad intern engineer and am looking to streamline the file sorting process for those at my workplace. I am attempting to make a python program that displays an image and has buttons below than when pressed move that photo into a specific folder.
The biggest difficulty so far is that I have no experience with python but that is what the company uses so im locked into it. I am able to create a messy program that displays a window with a photo and am yet to add buttons but that should be alright. My current concern is that it opens a new window every time it sorts a photo, as if the window is the photo rather than the photo being a part of the window. I will post my messy code below but any help would be appreciated. Please keep in mind im a complete python beginner, my only experience similar to this is in C#.
import os
import shutil
import tkinter as tk
import PIL
from PIL import ImageTk, Image
source = 'C:\\Source\\'
for file in os.listdir(source):
root = tk.Tk()
root.geometry("1920x1080")
photo = Image.open(source+file).resize((750,500), Image.ANTIALIAS)
img = ImageTk.PhotoImage(photo)
panel = tk.Label(root, image = img)
panel.image = img
panel.pack(side = "top", fill = "both")
print('Enter Destination Directory')
dest = input()
shutil.move(source+file, dest)
root.destroy()
I think it may be opening new windows because you are destroying root.
You need to define and destroy your root variable outside of your main for loop. Each time you loop, you create a new tk.Tk object and then, destroy it.
I am writing a program using Tkinter that is to be eventually compiled into an exe using py2exe. I want to include an icon with it for use on the windows. It will be the same one as I have packed as the icon for the exe. Is there a way to include the icon in Tkinter, either by locating the exe file or using a file-like object? I know that win32api can find the current exe file that's running, but I believe that py2exe extracts the original file to temp, and then runs it, so the original exe couldn't be found that way. I also thought of putting it in an include folder, but I don't know if the cwd would be set correctly for that. Thanks for the help in advance!
Tk images have a -data option which lets you embed the image within the code. You just have to base64-encode the image. I think the image has to originally be in the GIF format.
Here's a working example:
import Tkinter as tk
root = tk.Tk()
data = '''R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9P
T6Ai8P8A/////////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYY
fh8GIEvpoUZcmtOKAO5rLMva0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYw
YtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eTYhJDQ3woDGl7foNiKBV7aYeEkHEi
gnKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOsNYa2q7mcirC5I5Fo
fsK6hcHHgsSgx4a9yzXK0rrV19gRADs=
'''
img = tk.PhotoImage(data=data)
label = tk.Label(image=img)
label.pack()
root.mainloop()
You can embedd the icon in the py2exe binary with the icon_resources option
setup(windows=[
{'script':'toto.py', "icon_resources": [(1, "toto.ico")]},
],
Then you can retrieve it with the windows api
import win32gui, win32api, win32con
from ctypes import c_int, windll
hicon = win32gui.CreateIconFromResource(win32api.LoadResource(None, win32con.RT_ICON, 13), True)
and then attach to a window as long as you know his HWND.
windll.user32.SendMessageA(c_int(hwnd), c_int(win32con.WM_SETICON), c_int(win32con.ICON_SMALL), c_int(hicon))
The 13 constant used in the LoadResource has been retrieved with a tool like ResourceHacker. In ResourceHacker, it corresponds to the folder name of the icon. I don't know how it is calculated by py2exe and if there is a way to force this value.
I don't know also if there is a pure TkInter way to do that and if the icon can be used as-is in a tkinter window.
I hope it helps