简体   繁体   中英

How can I Iterate through a list of Images and Display them in Tkinter

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))

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()

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()

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()

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM