Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
230 views
in Technique[技术] by (71.8m points)

python - Tkinter animation will not work

I am trying to display the animation from my gif image. From my previous question, I discovered that Tkinter doesn't animate images automatically. My Tk interface shows the first frame of the image, and when I click the button to play its animation, it does nothing. It's likely something to do with the command associated with the button. Here's the code:

from Tkinter import *
import Tkinter

root = Tk()

photo_path = "/users/zinedine/downloads/091.gif"
photo = PhotoImage(
    file = photo_path
    )

def run():
    frame = 1
    while True:
        try:
            photo = PhotoImage(
                file = photo_path,
                format = "gif - {}".format(frame)
                )
            frame = frame + 1

        except Exception: # This because I don't know what exception it would raise
            frame = 1
            break

picture = Label(image = photo)
picture.pack()
picture.configure(run())

animate = Button(
    root,
    text = "animate",
    command = run()
    )
animate.pack()

root.geometry("250x250+100+100")
root.mainloop()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use the universal Tk widget after() method to schedule a function to run after a specified delay given in milliseconds. This only happens once, so typically the function itself also calls after() to perpetuate the process.

In the code below a custom AnimatedGif container class is defined which loads and holds all the frames of animated sequence separately in a list which allows quick (random) access to them using [] indexing syntax. It reads individual frames from the file using the -index indexvalue image format suboption mentioned on the photo Tk manual page.

I got the test image shown below from the Animation Library website.

test image

Here's how things should look when it's initially started.

screenshot of program window at start up

You should be able use the same technique to animate multiple images or those that are attached to other kinds of widgets, such as Button and Canvas instances.

try:
    from tkinter import *
except ImportError:
    from Tkinter import *  # Python 2


class AnimatedGif(object):
    """ Animated GIF Image Container. """
    def __init__(self, image_file_path):
        # Read in all the frames of a multi-frame gif image.
        self._frames = []

        frame_num = 0  # Number of next frame to read.
        while True:
            try:
                frame = PhotoImage(file=image_file_path,
                                   format="gif -index {}".format(frame_num))
            except TclError:
                break
            self._frames.append(frame)
            frame_num += 1

    def __len__(self):
        return len(self._frames)

    def __getitem__(self, frame_num):
        return self._frames[frame_num]


def update_label_image(label, ani_img, ms_delay, frame_num):
    global cancel_id
    label.configure(image=ani_img[frame_num])
    frame_num = (frame_num+1) % len(ani_img)
    cancel_id = root.after(
        ms_delay, update_label_image, label, ani_img, ms_delay, frame_num)

def enable_animation():
    global cancel_id
    if cancel_id is None:  # Animation not started?
        ms_delay = 1000 // len(ani_img)  # Show all frames in 1000 ms.
        cancel_id = root.after(
            ms_delay, update_label_image, animation, ani_img, ms_delay, 0)

def cancel_animation():
    global cancel_id
    if cancel_id is not None:  # Animation started?
        root.after_cancel(cancel_id)
        cancel_id = None


root = Tk()
root.title("Animation Demo")
root.geometry("250x125+100+100")
ani_img = AnimatedGif("small_globe.gif")
cancel_id = None

animation = Label(image=ani_img[0])  # Display first frame initially.
animation.pack()
Button(root, text="start animation", command=enable_animation).pack()
Button(root, text="stop animation", command=cancel_animation).pack()
Button(root, text="exit", command=root.quit).pack()

root.mainloop()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...