So, my goal is to create a sort of slideshow within Tkinter. I have a list of images like Images = ["1.png", "2.png", ...], I want to be able to iterate through the list and display each image in a Tkinter window, the concept is simple and as follows:
- Display Image 1
- 30 Second Delay
- Display Image 2
- 30 Second Delay
- Display Image 3
I have managed to iterate the images using a button press, however, I do not want to have to click a button as it is meant to imitate a slideshow, I also attempted looping a function but the time.sleep() function does not delay in the correct way because of how Tkinter behaves.
I managed to achieve the above using mostly source code from here, and I would appreciate a little hand achieving the above.
My Code:
from tkinter import *
from PIL import ImageTk, Image
Window = Tk()
Window.geometry("1920x1080")
Window.resizable(0, 0)
Label1 = Label(Window)
Label1.pack()
Images = iter(["1.png", "2.png", "3.png", "4.png", "5.png",
"6.png", "7.png", "8.png", "9.png", "10.png"])
def Next_Image(Val):
try:
Image1 = next(Images)
except StopIteration:
return
Image1 = ImageTk.PhotoImage(Image.open(Image1))
Label1.Image = Image1
Label1["image"] = Image1
Button1 = Button(text = "Next image", command =
lambda:Next_Image(1))
Button1.place(x = 50, y = 50)
Next_Image(1)
Window.mainloop()
I also attempted to use .after()
, however, it did not display each image, it skipped from the first image to the last straight away with the compounded delay.
for x in range(1, 11):
Window.after(1000, lambda : Next_Image(1))
CodePudding user response:
You need to create a function that gets the image off of the list and displays it, and then uses after
to call itself again in a second. Your main program needs to call this exactly once, and then it will run until it runs out of things to do.
Here's a working example that uses a text string for simplicity, but it should be obvious how to modify it to use images.
import tkinter as tk
images = iter(["1.png", "2.png", "3.png", "4.png", "5.png",
"6.png", "7.png", "8.png", "9.png", "10.png"])
def next_image():
try:
image = next(images)
label.configure(text=image)
root.after(1000, next_image)
except StopIteration:
return
root = tk.Tk()
label = tk.Label(root, width = 40, height=4)
label.pack()
next_image()
root.mainloop()
CodePudding user response:
You can use .after()
to switch image periodically:
from itertools import cycle
...
# use cycle() instead of iter()
Images = cycle([f"{i}.png" for i in range(1, 5)])
...
def next_image():
# use next() to get next image in the cycle list
Label1.image = ImageTk.PhotoImage(file=next(Images))
Label1['image'] = Label1.image
# switch image again after 1 second
Label1.after(1000, next_image)
next_image() # start the loop
Window.mainloop()
CodePudding user response:
This worked, Thank you @acw1668 and @Bryan Oakley.
from tkinter import *
from PIL import ImageTk, Image
Window = Tk()
Window.geometry("1920x1080")
Window.resizable(0, 0)
Label1 = Label(Window)
Label1.pack()
Images = iter(["1.png", "2.png", "3.png", "4.png", "5.png", "6.png",
"7.png", "8.png", "9.png", "10.png"])
def Next_Image(Val):
try:
Image1 = next(Images)
except StopIteration:
return
Image1 = ImageTk.PhotoImage(Image.open("BuyingConfig\\" Image1))
Label1.Image = Image1
Label1["image"] = Image1
Window.after(3000, lambda:Next_Image(1))
Window.after(0, lambda:Next_Image(1))
Window.mainloop()