-
Notifications
You must be signed in to change notification settings - Fork 15
/
AnimatedGif.py
74 lines (63 loc) · 2.72 KB
/
AnimatedGif.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
""" AnimatedGIF - a class to show an animated gif without blocking the tkinter mainloop()
Copyright (c) 2016 Ole Jakob Skjelten <[email protected]>
Released under the terms of the MIT license (https://opensource.org/licenses/MIT) as described in LICENSE.md
"""
import sys
import time
try:
import Tkinter as tk # for Python2
except ImportError:
import tkinter as tk # for Python3
class AnimatedGif(tk.Label):
"""
Class to show animated GIF file in a label
Use start() method to begin animation, and set the stop flag to stop it
"""
def __init__(self, root, gif_file, delay=0.04):
"""
:param root: tk.parent
:param gif_file: filename (and path) of animated gif
:param delay: delay between frames in the gif animation (float)
"""
tk.Label.__init__(self, root)
self.root = root
self.gif_file = gif_file
self.delay = delay # Animation delay - try low floats, like 0.04 (depends on the gif in question)
self.stop = False # Thread exit request flag
self._num = 0
def start(self):
""" Starts non-threaded version that we need to manually update() """
self.start_time = time.time() # Starting timer
self._animate()
def stop(self):
""" This stops the after loop that runs the animation, if we are using the after() approach """
self.stop = True
def _animate(self):
try:
self.gif = tk.PhotoImage(file=self.gif_file, format='gif -index {}'.format(self._num)) # Looping through the frames
self.configure(image=self.gif)
self._num += 1
except tk.TclError: # When we try a frame that doesn't exist, we know we have to start over from zero
self._num = 0
if not self.stop: # If the stop flag is set, we don't repeat
self.root.after(int(self.delay*1000), self._animate)
def start_thread(self):
""" This starts the thread that runs the animation, if we are using a threaded approach """
from threading import Thread # We only import the module if we need it
self._animation_thread = Thread()
self._animation_thread = Thread(target=self._animate_thread).start() # Forks a thread for the animation
def stop_thread(self):
""" This stops the thread that runs the animation, if we are using a threaded approach """
self.stop = True
def _animate_thread(self):
""" Updates animation, if it is running as a separate thread """
while self.stop is False: # Normally this would block mainloop(), but not here, as this runs in separate thread
try:
time.sleep(self.delay)
self.gif = tk.PhotoImage(file=self.gif_file, format='gif -index {}'.format(self._num)) # Looping through the frames
self.configure(image=self.gif)
self._num += 1
except tk.TclError: # When we try a frame that doesn't exist, we know we have to start over from zero
self._num = 0
except RuntimeError:
sys.exit()