Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a fade out effect in Tkinter? My code crashes

Tags:

python

tkinter

I am building an application in Tkinter with a custom window through overrideredirect. I have bound my self-designed X button to the function below. Closing the app using my button works fine, and it does fade out, but after a few seconds the window reappears, gets stuck in a loop (that's what it looks like) and crashes. It should just quit, which is what it did before I added the fadeout loop. Can someone tell me why the program reappears then crashes or offer a better alternative for a fadeout effect when closing the app (I know there are more sophisticated toolkits but I need to use Tkinter in this case)?

Thanks

def CloseApp(event):
if InProgress==False: #InProgress boolean defined elsewhere in program
    if tkMessageBox.askokcancel("Quit","Do you really wish to quit?"):
        n=1
        while n != 0:
            n -= 0.1
            QuizWindow.attributes("-alpha", n)
            time.sleep(0.02)                                  
        Window.destroy() #I've also tried using the quit() method, not that it would make a difference
else:
    if tkMessageBox.askokcancel("Quit"," If you quit now you will lose your progress and have to start again. Are you sure you want to quit?"):
        n=1
        while n != 0:
            n -= 0.1
            QuizWindow.attributes("-alpha", n)
            time.sleep(0.02)
        Window.destroy() 
like image 250
user3435111 Avatar asked Jan 10 '23 23:01

user3435111


1 Answers

You have two problems. First, you should never do exact comparisons to floating point numbers. Floating point math is imprecise, and n may never actually be 0.0000000....

Second, you should never call time.sleep in a GUI program. If you want to run something every .02 seconds, use after.

Here's an example:

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        b = tk.Button(self, text="Click to fade away", command=self.quit)
        b.pack()
        self.parent = parent

    def quit(self):
        self.fade_away()

    def fade_away(self):
        alpha = self.parent.attributes("-alpha")
        if alpha > 0:
            alpha -= .1
            self.parent.attributes("-alpha", alpha)
            self.after(100, self.fade_away)
        else:
            self.parent.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
like image 157
Bryan Oakley Avatar answered Jan 29 '23 23:01

Bryan Oakley