Search code examples
pythontkintercountlabelcountdown

Python tKinter - Is there a way to get rid of existing label before making a new count-up?


I've found a countdown code and modified it so it counts up to a given number. It all works, but every time I push the button to run the functions, the existing label stays there and the new one gets put on top. (If I pack them, they get put underneath each other). It's because they get created inside the function, but I can't seem to find a way around it.

It might be a newbie question, but I'm just trying to learn :)

Code:

import time
from tkinter import *
import threading

betongtrykk = Tk()
betongtrykk.geometry("400x300")

canvas = Canvas(
    betongtrykk,
    bg = "#FFFFFF",
    height = 300,
    width = 400,
    bd = 0,
    highlightthickness = 0,
    relief = "ridge"
)

canvas.place(x = 0, y = 0)

utnyttelseres = 65

def cd(timer_label_obj,ts):
    while ts < utnyttelseres:
        timer_label_obj.config(text=ts)
        ts+=1
        timer_label_obj.place(x=100, y=150)
        time.sleep(0.01)
        if ts == utnyttelseres:
            timer_label_obj.config(text=utnyttelseres)

def countup(t):
    timer = Label(betongtrykk)
    th = threading.Thread(target=cd,args=[timer,t])
    th.start()

submitCountdown = Button(betongtrykk, padx=5, pady=5, text="Submit", font=("Arial", 20), command= lambda:countup(0))
submitCountdown.place(x= 100, y=100)

betongtrykk.mainloop()

Solution

  • You can use the <widget>.destroy() method on the Label widget once the countdown is complete. This method will delete the widget and remove it from the screen.

    Corrected Code:

    import time
    from tkinter import *
    import threading
    
    betongtrykk = Tk()
    betongtrykk.geometry("400x300")
    
    canvas = Canvas(
        betongtrykk,
        bg = "#FFFFFF",
        height = 300,
        width = 400,
        bd = 0,
        highlightthickness = 0,
        relief = "ridge"
    )
    
    canvas.place(x = 0, y = 0)
    
    utnyttelseres = 65
    
    def cd(timer_label_obj,ts):
        while ts < utnyttelseres:
            timer_label_obj.config(text=ts)
            ts+=1
            timer_label_obj.place(x=100, y=150)
            time.sleep(0.01)
            if ts == utnyttelseres:
                timer_label_obj.config(text=utnyttelseres)
                timer_label_obj.destroy()
    
    def countup(t):
        timer = Label(betongtrykk)
        th = threading.Thread(target=cd,args=[timer,t])
        th.start()
    
    submitCountdown = Button(betongtrykk, padx=5, pady=5, text="Submit", font=("Arial", 20), command = lambda:countup(0))
    submitCountdown.place(x= 100, y=100)
    
    betongtrykk.mainloop()
    

    Alternate Solution:

    If you want the countdown label to be removed JUST before the next countdown starts, you can make timer a global variable and use the .destroy() method on it before creating the new countdown label in countup.

    def cd(timer_label_obj,ts):
        while ts < utnyttelseres:
            timer_label_obj.config(text=ts)
            ts+=1
            timer_label_obj.place(x=100, y=150)
            time.sleep(0.01)
            if ts == utnyttelseres:
                timer_label_obj.config(text=utnyttelseres)
    
    def countup(t):
        global timer
        try:
            timer.destroy()
        except NameError:
            pass
        
        timer = Label(betongtrykk)
        th = threading.Thread(target=cd,args=[timer,t])
        th.start()