Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Tkinter Display Loading Animation While Performing Certain Tasks

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"
like image 574
COCO Avatar asked Apr 28 '26 04:04

COCO


1 Answers

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()
like image 154
acw1668 Avatar answered Apr 30 '26 18:04

acw1668



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!