简体   繁体   中英

How to handle Invalid command name error, while executing (“after” script) in tkinter python using OOP Approach

I have seen a lot of questions similar to mine on this thread however none of them are relatable to the OOP tkinter method that I am using. I am getting the error:

invalid command name "2452827444616callback"
while executing "2452827444616callback"
("after" script)

This happens because I am using the "after" function in a recursive loop but get this error whenever I close the tkinter window and try to open it back up again.

A simple example of my code structure which generates this problem is below:

import tkinter as tk

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        
        tk.Frame.__init__(self, parent, *args, **kwargs)
        
        self._parent = parent

        self.var = tk.IntVar()
        tk.Label(self._parent, textvariable=self.var).pack()
        
        self.callback()     #This starts the recursion loop
        
    def callback(self):
        global after_id
        self.var.set(self.var.get() + 1)
        after_id = root.after(500, self.callback)


if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

Similar issues have been solved like in this thread:

How to handle Invalid command name error, while executing ("after" script) in tkinter python

However, I cannot seem to get it to work due to the different structure that I am using with the OOP tkinter approach. Any help would be greatly appreciated.

You can cancel the after task when the frame is being destroyed by calling after_cancel() inside __del__() function of MainApplication class:

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.var = tk.IntVar()
        tk.Label(self, textvariable=self.var).pack()
        
        self.callback()     #This starts the recursion loop
    
    def __del__(self):
        self.after_cancel(self.after_id)

    def callback(self):
        self.var.set(self.var.get()+1)
        self.after_id = self.after(500, self.callback)

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