'How do I stop this timer when it reaches a number?

import tkinter as tk

counter = 0
def counter_label(label):
    counter = 0
    def count():
        global counter
        counter += 1
        label.config(text=str(counter))
        label.after(10, count)
    count()

root = tk.Tk()
root.title("counter")
label= tk.Label(root, fg = "dark green")
label.pack()
counter_label(label)
button = tk.Button(root, text="stop", width=40, command = root.destroy)
button.pack()
root.mainloop()


Solution 1:[1]

You can do it by not scheduling the count() function to be called again (via the after() method) after the counter has reached or exceeded a specified limit value.

You also don't need to use a global variable. An advantage of that being that it would allow the same function to be applied to than one Label at a time — each using its own counter. Note I also added an optional rate argument which controls how much the counter is incremented each iteration.

import tkinter as tk

def counter_label(label, limit, rate=1):
    """Update counter display on label at given rate until it reaches limit."""
    counter = 0
    def count():
        nonlocal counter
        counter += rate
        label.config(text=str(counter))
        if counter < limit:
            label.after(10, count)
    count()  # Start counting.

root = tk.Tk()
root.title("counter")
label= tk.Label(root, fg="dark green")
label.pack()
counter_label(label, 500)
button = tk.Button(root, text="stop", width=40, command=root.destroy)
button.pack()
root.mainloop()

Generalizing

Here's a more generic version of the counter_label() function that avoids the use of hardcoded quantities and calculates what it needs from the arguments passed to it.

import tkinter as tk

def counter_label(label, limit, duration, updates_per_sec):
    """ Update counter display on label over time period at given updates per
        second until it reaches limit.
    """
    incr_per_sec = limit / duration
    incr_per_call = incr_per_sec / updates_per_sec
    ms_delay = int(1/updates_per_sec * 1000)

    counter = 0
    def count():
        nonlocal counter
        counter += incr_per_call
        label.config(text=format(counter, '.3f'))
        if counter < limit:
            label.after(ms_delay, count)
    count()  # Start counting.

root = tk.Tk()
root.title("counter")
label= tk.Label(root, fg="dark green")
label.pack()
counter_label(label, 1000, 5, 20)
button = tk.Button(root, text="stop", width=40, command=root.destroy)
button.pack()
root.mainloop()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1