简体   繁体   中英

Python Tkinter Label not responding

I am trying to make a loading and a GIF would be a lot helpful if it was supported in python tkinter. But since it is not supported, so I put all the frame-by-frame pictures in the list that makes a loading when played continuously (using assign_pic function) and then I created a label (called lab_loading) of which I change the picture after 200ms by calling the start_anim function. I am calling the assign_pic function in a loop which I think causes this error. See my source code below and the video I provided to understand this problem clearly.

Video: https://drive.google.com/file/d/1WHwZqvd8vXz-ehXbQ_fRtrKPEyFLKrVe/view?usp=sharing

Source code:

from time import sleep
from tkinter import Tk, Label
from PIL import ImageTk, Image


class Loading(Tk):
    def __init__(self):
        super().__init__()
        self.title('Loading')
        self.geometry('250x217')

        self.address = getcwd()
        self.imgs_list = []
        self.loadingImgsList(self.address)

    # This method Puts all the images in the list
    def loadingImgsList(self, curAddress):
        address = f'{curAddress}\\loading'
        self.imgs_list = [(ImageTk.PhotoImage(Image.open(
            f"{address}\\{i}.png"))) for i in range(1, 4)]

    # This mehtod assigns the picture from the list via index (ind) number from the imgs_list list and
    # updates the GUI when called.
    def assign_pic(self, ind):
        lab_loading.config(image=self.imgs_list[ind])
        self.update_idletasks()
        sleep(0.2)

    def start_anim(self):
        ind = 0
        b = 0
        while (b < 300):
            if ind == 2:
                ind = 0
            else:
                ind += 1

            self.after(200, self.assign_pic, ind)
            b += 1


if __name__ == "__main__":
    root = Loading()
    lab_loading = Label(root, image='')
    lab_loading.pack()
    root.start_anim()
    root.mainloop()

I Tried to make start_anime function recursive but it was still the same. I don't know why this is happening. I also made the loop finite but it was still not working. So a solution to this problem or even a better suggestion would highly be appreciated.

you shouldn't be using sleep inside tk, as it blocks python from handling user actions.

the way you do animation in tk is by using the after method, to call a function that would update the canvas, this function will call after again, until the animation is complete.

# everything before this function should be here

    self.ind = 0 #somewhere in __init__
    def assign_pic(self):
        if self.ind < len(imgs_list):
            lab_loading.config(image=self.imgs_list[self.ind])
            self.ind += 1
            root.after(500,self.assign_pic) # time in milliseconds
        else:
            print("done") # do what you want after animation is done

if __name__ == "__main__":
    root = Loading()
    lab_loading = Label(root, image='')
    lab_loading.pack()
    root.after(100,root.assign_pic)
    root.mainloop()

the after function schedules the given function after a certain delay, during which the GUI is free to respond to any action.

Edit: after method takes argument in milliseconds not in seconds, i had the input in it in seconds instead of milliseconds, it's now fixed.

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