Zachary
Zachary

Reputation: 27

How to make a button cancel a .after command

I currently have a function that shows a new screen (lets call it A), then does a countdown of 10 seconds. After the 10 seconds, it takes the user to a new screen (B). I would like to make the .after command not execute if the user clicks a button on screen 'A' before the 10 seconds.

class MainGate3(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        background_image = tk.PhotoImage(file="Sylvanas.png")  # Displays whats in the file
        background_label = tk.Label(self, image=background_image)  # Makes tk.Label display the background_image
        background_label.place(x=0, y=0, relwidth=1, relheight=1)  # Adjusts the height/width

        background_label.image = background_image  # Recognises the label as an image

        def gate():
            controller.show_frame("MainGate4")
            button1.after(10000, lambda:controller.show_frame("MainMenu"))

        button1 = tk.Button(self, text="Commence Battle", bg="black", fg="white", height=2, width=20,
                            command=gate)
        button1.place(x="712", y="433")

class MainGate4(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        background_image = tk.PhotoImage(file="Sylvanas1.png")  # Displays whats in the file
        background_label = tk.Label(self, image=background_image)  # Makes tk.Label display the background_image
        background_label.place(x=0, y=0, relwidth=1, relheight=1)  # Adjusts the height/width

        background_label.image = background_image  # Recognises the label as an image

        button1 = tk.Button(self, text="Parry Right", bg="black", fg="white", height=2, width=20,
                            command=lambda: controller.show_frame("MainGate3"))
        button2 = tk.Button(self, text="Parry Left", bg="black", fg="white", height=2, width=20,
                            command=lambda: controller.show_frame("MainGate3"))
        button3 = tk.Button(self, text="Dodge", bg="black", fg="white", height=2, width=20,
                            command=lambda: controller.show_frame("MainGate3"))
        button1.place(x="83", y="140")
        button2.place(x="83", y="240")
        button3.place(x="83", y="340")

Upvotes: 0

Views: 376

Answers (1)

Henry Yik
Henry Yik

Reputation: 22503

The after method returns an identifier. You can use the identifier to cancel by after_cancel method later.

import tkinter as tk

class GUI(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.action = None
        tk.Button(self,text="Print in 10 sec",command=self.callback).pack()
        tk.Button(self, text="Cancel print", command=self.cancel_callback).pack()

    def callback(self):
        self.action = self.after(10000,lambda: print ("Hi"))

    def cancel_callback(self):
        if self.action:
            self.after_cancel(self.action)
            print ("Print cancelled")

root = GUI()
root.mainloop()

Upvotes: 4

Related Questions