I have a script where I'm going through a loop, and once a condition is met, an image is added to my Tkinter window. I'm able to add and resize the image in Tkinter, however what I want to do is replace the image (or rather, just add another image on top of the previous one), as I go through my while loop. However, while Images
is redefined as 'greencar.jpg', the actual image is not posted in the window.
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
Images=()
class Example(Frame):
global Images
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open(Images)
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
def main():
global Images
x=0
root.update_idletasks()
while x<100000:
x+=1
if x == 500:
Images='mountain.jpg'
e = Example(root)
e.pack(fill=BOTH, expand=YES)
root.update_idletasks()
if x == 5000:
Images='greencar.jpg'
e = Example(root)
e.pack(fill=BOTH, expand=YES)
root.update_idletasks()
root = tk.Tk()
root.geometry('600x600')
main()
root.mainloop()
Edit: So trying Saad's solution works really nicely, but I tried to extend it one step further, by implementing a couple of functions and a second loop.
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
Images= "mountain.jpg"
class Example(Frame):
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open(Images)
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
def change_image(self, file):
"""Change background image of the window."""
size = (self.winfo_width(), self.winfo_height())
self.image = Image.open(file).resize(size)
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image=self.background_image)
def add(x):
return x+3
def subtract(x):
return x-1
def check_image(x=0):
x=add(x)
if x >= 1000:
return # Break the loop
if x == 50:
e.change_image('mountain.jpg')
elif x == 500:
e.change_image('greencar.jpg')
print(x)
root.after(1, check_image,subtract(x))
def loop():
while True:
question=input('go again?')
if question == 'n':
break
check_image(x=0)
root = tk.Tk()
root.geometry('600x600')
e = Example(root)
e.pack(fill=BOTH, expand=YES)
loop()
root.mainloop()
So what I wanted was the option for the user to go through the loop again. So I made another function to do this. However, check_image()
no longer loops. It stops at the first iteration. If I break my while in loop()
(by typing 'n'), then it will go through the check_image()
iterations, however, the images no longer update. In short, I seem to have broken the program again, but I don't quite understand why.
There are a couple of issues with your code that needs to be addressed.
To replace the image you have to create a new instance of PhotoImage
with file='new_image.png'
argument every time and then self.background.configure(image=new_image_instance)
. As in your main
function, you are just creating a new Example
widget in the same window.
I don't recommend using update_idletasks()
in a while loop instead the whole while loop can be replaced by after(ms, func, *args)
method of Tkinter.
def check_image(x=0): # Break the loop if x >= 100000: return if x == 500: e.change_image('mountain.jpg') elif x == 5000: e.change_image('greencar.jpg') root.after(1, check_image, x+1)
I think it would be best to just create a method that will change the image of the Example
widget.
def change_image(self, file): """Change background image of the window.""" size = (self.winfo_width(), self.winfo_height()) self.image = Image.open(file).resize(size) self.background_image = ImageTk.PhotoImage(self.image) self.background.configure(image=self.background_image)
Complete Code:
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
Images= "image.png"
class Example(Frame):
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open(Images)
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
def change_image(self, file):
"""Change background image of the window."""
size = (self.winfo_width(), self.winfo_height())
self.image = Image.open(file).resize(size)
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image=self.background_image)
def check_image(x=0):
if x >= 100000: return # Break the loop
if x == 500:
e.change_image('mountain.jpg')
elif x == 5000:
e.change_image('greencar.jpg')
root.after(1, check_image, x+1)
root = tk.Tk()
root.geometry('600x600')
e = Example(root)
e.pack(fill=BOTH, expand=YES)
check_image()
root.mainloop()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.