So I made a script in python with Tkinter and the thing is that the first Tkinter window pops up without problems but when the code goes to the second window it says :
_tkinter.TclError: image "pyimage1" doesn't exist
and I didn't find anything that helped me, could someone help me please ?
Here is the code :
from Tkinter import *
from PIL import ImageTk, Image
def choose():
global name, chosen
name = name1.get()
chosen = chosen1.get()
print name
print chosen
root0.quit()
root0 = Tk()
name1 = Entry(root0)
name1.pack()
chosen1 = Entry(root0)
chosen1.pack()
Button(root0, text="ENTER", command=choose).pack()
root0.mainloop()
root = Tk()
img = ImageTk.PhotoImage(Image.open('person1.png'))
panel1 = Label(root, image = img)
panel1.pack(side="left")
img2 = ImageTk.PhotoImage(Image.open('person2.png'))
panel2 = Label(root, image = img2)
panel2.pack(side="right")
root.mainloop()
by the way, the python version is 2.7
This is a side effect of using 2 roots (Tk() instances). The images default to associate with the first root window. The quick fix is to provide the image with the correct root:
img2 = ImageTk.PhotoImage(Image.open('person2.png'), master=root)
The proper fix is to never use more than one Tk(). Put all your code into Frame instances, and then destroy one and load the other when the time is right:
import Tkinter as tk
def choose():
global name, chosen
name = name1.get()
chosen = chosen1.get()
print name
print chosen
frame0.destroy() # kill this frame
frame1.pack() # open new frame
root = tk.Tk()
frame0 = tk.Frame(root)
name1 = tk.Entry(frame0)
name1.pack()
chosen1 = tk.Entry(frame0)
chosen1.pack()
tk.Button(frame0, text="ENTER", command=choose).pack()
frame1 = tk.Frame(root)
img = ImageTk.PhotoImage(Image.open('person1.png'))
panel1 = tk.Label(frame1, image = img)
panel1.pack(side="left")
img2 = ImageTk.PhotoImage(Image.open('person2.png'))
panel2 = tk.Label(frame1, image = img2)
panel2.pack(side="right")
#start the program
frame0.pack() # load frame0
root.mainloop()
Note I also moved you away from the evil wildcard imports (from module import *).
Related
This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 8 months ago.
I've tried several methods but did not worked. Suppose I am working on a project that changes the picture when the button is clicked.
Well as I know, all it did is I just clicked 1 time and the image turned white and I can not click it anymore. Quick! I need to complete this project in 1 hour deadline. Here is the code.
# Modules
from tkinter import *
from PIL import Image, ImageTk
# Functions
def change_img():
global curr_img
global root
global image1
image1 = Image.open(f"Hamster {curr_img + 1}.jpg")
image1 = image1.resize((100, 60))
img1 = ImageTk.PhotoImage(image1)
btn.configure(image=img1, command=change_img)
root.update()
curr_img += 1
# Main Window
root = Tk()
root.title("Picture Change")
root.geometry("300x150")
root.config(bg="black")
# Adding Objects
curr_img = 1
Label(root, text="My Favorite Animal", fg="white", bg="black", font=("Arial bold", "20")).pack() # This is a label.
image1 = Image.open("Hamster 1.jpg") # First we open the image and save it into a variable.
image1 = image1.resize((100,60)) # Resizes the image.
img1 = ImageTk.PhotoImage(image1) # Create a ImageTK object from the image1 variable.
btn = Button(image = img1, command=change_img) # Create a label and put the image into it.
btn.pack() # Pack the label that contains the image. Now, we repeat the process.
# Mainloop
root.mainloop()
Thanks if the answer is quick and accurate. Comment, thanks very much too.
You create the next image in the change_img() function and when the function exits the reference to the image is garbage collected. You can save a reference to the image in the button widget:
btn.configure(image=img1, command=change_img)
btn.image = img1 # Save a reference to the new image
img= (Image.open("image/frame.png")).resize((240, 240), Image.ANTIALIAS)
new_image = ImageTk.PhotoImage(img)
panel = tk.Label(right_workspace, image=new_image)
panel.pack(side = "top", fill = "none", expand = "none", pady=29)
Thats my label with its image background. Now how can I change this background by a function so everytime my program generates a new qrcode from an input it replaces previous background?
I gather what you're doing, but please leave a minimum reproducible code in future.
Here's an example of how you'd create a functioning tkinter GUI that displays a random image from a list of QR .pngs in a set folder when the button is pressed. You should be able to adapt this to the other part of your program that generates the QR code for you.
import tkinter as tk
from PIL import Image, ImageTk
import os
import random
class QrGenerator:
def __init__(self, main):
self.main = main
self.panel = tk.Label(main)
self.panel.grid(row=0, column=0)
self.button = tk.Button(main, text='Random QR', command=self.random_qr)
self.button.grid(row=1, column=0)
def random_qr(self):
fp = r'C:\Filepath\QR Codes Folder'
os.chdir(fp)
qr_code = random.choice(os.listdir(fp))
print(qr_code)
img = Image.open(qr_code).resize((240, 240), Image.ANTIALIAS)
new_image = ImageTk.PhotoImage(img)
self.panel.configure(image=new_image)
self.panel.image = new_image
if __name__ == '__main__':
root = tk.Tk()
gui = QrGenerator(root)
root.mainloop()
Currently, the code chooses images from a folder and displays it on the tkinter window. I can click 'Next image' to see the next image from the folder. I would like to make the images clickable, so that it take would take me to a specified link. I can make it clickable but not sure how to bind the different links to each image. It will get confusing if I were to randomize the images(planning to do this later)
import tkinter as tk
from tkinter.filedialog import askdirectory
import os
img_list = []
def save_to_list(event):
click_loc = [event.x, event.y]
print ("you clicked on", click_loc)
img_list.append(click_loc)
def next_img():
img_label.img = tk.PhotoImage(file=next(imgs))
img_label.config(image=img_label.img)
root = tk.Tk()
root.geometry('500x500')
# Choose multiple images
img_dir = askdirectory(parent=root, initialdir="./yoga_Images/", title='Choose folder')
os.chdir(img_dir)
imgs = iter(os.listdir(img_dir))
img_label = tk.Label(root)
img_label.pack()
img_label.bind("<Button-1>",save_to_list)
btn = tk.Button(root, text='Next image', command=next_img)
btn.pack()
next_img()
root.mainloop()
You can simply specify a image object when creating a button.
from PIL import Image, ImageTk
import tkinter as tk
def example():
print("Clickable Image!")
root = tk.Tk()
image = Image.open("image.png")
btnPhoto= ImageTk.PhotoImage(image)
imgBtn = tk.Button(root, image=btnPhoto, command=example)
imgBtn.pack()
root.mainloop()
Here is some code if you want to make multiple clickable images, don't forget to specify your image directory (Apologies for using list comprehensions, I know they are somewhat confusing).
from PIL import Image, ImageTk
import tkinter as tk
import os
def example():
print("Clickable Image!")
root = tk.Tk()
imgDir = "imgs"
images = [ImageTk.PhotoImage(Image.open(os.path.join(imgDir, imgName))) for imgName in os.listdir(imgDir)]
for img in images:
imgBtn = tk.Button(root, image=img, command=example)
imgBtn.pack()
root.mainloop()
I expect the same output for both of the scripts below.
But I don't get the image on the button when I execute Script 1. However, Script 2 works well.
Script 1
from Tkinter import *
class fe:
def __init__(self,master):
self.b=Button(master,justify = LEFT)
photo=PhotoImage(file="mine32.gif")
self.b.config(image=photo,width="10",height="10")
self.b.pack(side=LEFT)
root = Tk()
front_end=fe(root)
root.mainloop()
Script 2
from Tkinter import *
root=Tk()
b=Button(root,justify = LEFT)
photo=PhotoImage(file="mine32.gif")
b.config(image=photo,width="10",height="10")
b.pack(side=LEFT)
root.mainloop()
The only reference to the image object is a local variable. When __init__ exits, the local variable is garbage collected so the image is destroyed. In the second example, because the image is created at the global level it never goes out of scope and is therefore never garbage collected.
To work around this, save a reference to the image. For example, instead of photo use self.photo.
its work
x1=Button(root)
photo=PhotoImage(file="Re.png")
x1.config(image=photo,width="40",height="40",activebackground="black"
,bg="black", bd=0,command=sil)
x1.place(relx=1,x=5, y=-5, anchor=NE)
but this is useless
def r():
x1=Button(root)
photo=PhotoImage(file="Re.png")
x1.config(image=photo,width="40",height="40",activebackground="black",
bg="black", bd=0,command=sil)
x1.place(relx=1,x=5, y=-5, anchor=NE)
r()
logo = PhotoImage(file = 'mine32.gif')
small_logo = logo.subsample(5, 5)
self.b.config(image = small_logo , compound = LEFT )
Unrelated answer, but this is the answer I was looking for when I first came here. Use this to resize the image before adding it to the button.
from PIL import Image, ImageTk
image = Image.open("path/to/image.png")
image = image.resize((25, 25), Image.ANTIALIAS)
self.reset_img = ImageTk.PhotoImage(image)
self.button = tk.Button(frame, image=self.reset_img)
from tkinter import *
root= Tk()
btnPlay = Button(root)
btnPlay.config(image=imgPlay, width="30", height="30")
btnPlay.grid(row=0, column=0)
root.mainloop()
I have this message: image "pyimage2" doesn't exist . I want to have multi windows with images , how ?
Here is my code:
import Image
import ImageTk
import Tkinter
def new():
wind = Tkinter.Tk()
wind.geometry('600x600') # This not work, why?
imageFile2 = Image.open("someimage2.jpg")
image2 = ImageTk.PhotoImage(imageFile2)
panel2 = Tkinter.Label(wind , image=image2)
panel2.place(relx=0.0, rely=0.0)
wind.mainloop()
master = Tkinter.Tk()
master.geometry('600x600') # This work fine
imageFile = Image.open("someimage.jpg")
image1 = ImageTk.PhotoImage(imageFile)
panel1 = Tkinter.Label(master , image=image1)
panel1.place(relx=0.0, rely=0.0)
B = Tkinter.Button(master, text = 'New image', command = new).pack()
master.mainloop()
Change wind = Tkinter.Tk() to wind = Tkinter.Toplevel():
def new():
wind = Tkinter.Toplevel()
wind.geometry('600x600')
That's all you need to change.
Reference:
Tkinter Toplevel