3

I have located this useful code for Tkinter animations from https://www.daniweb.com/programming/software-development/threads/396918/how-to-use-animated-gifs-with-tkinter ,supplied by "vegaseat".

I have adapted a similar design for displaying gifs animations to a project. I am wishing to implement this as a function to certain areas of a script, e.g. importing modules etc. I have tried a few approaches but when I called this as a function, it first runs the animation and then imports the module (as we would expect).

I guess I am exploring ways to get this to work concurrently...while the script is importing modules( or running another process where I wish to display the animation), the animation would be displayed, and then disappear, until the next call. Suggestions would be appreciated.

Thanks a lot.

# mimic an animated GIF displaying a series of GIFs
# an animated GIF was used to create the series of GIFs 
# with a common GIF animator utility

import time
from Tkinter import *
root = Tk()
imagelist = ["dog001.gif","dog002.gif","dog003.gif",
             "dog004.gif","dog005.gif","dog006.gif","dog007.gif"]
# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()
# create a list of image objects
giflist = []
for imagefile in imagelist:
    photo = PhotoImage(file=imagefile)
    giflist.append(photo)
# loop through the gif image objects for a while
for k in range(0, 1000):
    for gif in giflist:
        canvas.delete(ALL)
        canvas.create_image(width/2.0, height/2.0, image=gif)
        canvas.update()
        time.sleep(0.1)
root.mainloop()

EDIT: I am attempting to implement the code,below, per some helpful suggestions. The goal is to begin the animation, while the application is importing the modules in the "IMPORTS" function, and then have it destroyed after the imports are completed.

# Import modules
from Tkinter import *
from PIL import ImageTk
from PIL import Image
import os,time
from os.path import dirname
from os.path import join

def IMPORTS():
    import tkMessageBox
    from ttk import Combobox
    import csv,datetime
    import xlrd,xlwt
    import getpass
    import traceback
    import arcpy
    from arcpy import AddMessage
    import win32com.client


inGif = #root image (.gif)
FramesFolder = #Folder containing frames of the root image

W=Toplevel() 
W.wm_overrideredirect(True) # I wish to only display the widget spinning without the window frame

imagelist = [os.path.join(FramesFolder,s) for s in os.listdir(FramesFolder) if not s.endswith('db')]
# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(W,width=width, height=height)
canvas.pack()
# create a list of image objects
giflist = []
for imagefile in imagelist:
    photo = PhotoImage(file=imagefile)
    giflist.append(photo)

timer_id = None

def start_loading(n=0):
    global timer_id
    gif = giflist[n%len(giflist)]
    canvas.create_image(gif.width()//2, gif.height()//2, image=gif)
    timer_id = W.after(100, start_loading, n+1) # call this function every 100ms

def stop_loading():
    if timer_id:
        W.after_cancel(timer_id)
        canvas.delete(ALL)

start_loading()
IMPORTS()
stop_loading()
# The spinning widget should be completely destroyed before moving on...

It is returning

"NameError: name 'tkMessageBox' is not defined"

1 Answer 1

1

You can use Tk.after() and Tk.after_cancel() to start and stop the animation:

timer_id = None

def start_loading(n=0):
    global timer_id
    gif = giflist[n%len(giflist)]
    canvas.create_image(gif.width()//2, gif.height()//2, image=gif)
    timer_id = root.after(100, start_loading, n+1) # call this function every 100ms

def stop_loading():
    if timer_id:
        root.after_cancel(timer_id)
        canvas.delete(ALL)

Then, you can call start_loading() before the long process and call stop_loading() after the long process:

start_loading()
long_process() # your long process
stop_loading()
Sign up to request clarification or add additional context in comments.

10 Comments

I attempted to adapt your suggestions but now it is returning "image "pyimage19" doesn't exist" error. Also, perhaps you could explain this line timer_id = root.after(100, start_loading, n+1) # call this function every 100ms. Not sure how you are calling start_loading within its declarative scope
@COCO root.after() is to setup a timeout. First argument is the timeout period, second argument is the function to be called at the timeout time and the rest of the arguments are passed to the given function. Therefore, the statement is to setup a timeout to execute start_loading function with argument n+1 after 100ms. That means start_loading will be executed every 100ms until the timeout is canceled by after_cancel() function. The argument n of start_loading is used to select which image to be displayed.
Thank you for the clarification. I attempted to implement your suggestions, and updated my main post with the code. It is returning the error, as noted. Please let me know what you think we may need to change. Thanks a lot.
@COCO Did you import tkMessageBox module?
Hi acw, no, the messagebox will get imported in that function along with others...i dont think the messagebox needs to be imported prior to starting the animation, as it has no dependency, am i correct?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.