'Tkinter: how to make functions in after() work with variable objects?

I'm a beginner programmer and I'm trying to learn how to make code run continuously in tkinter.

My aim for testing is just to get a label to change colour every 2 seconds regardless of input.

I understand I can use the following format (with lbl initialised as a Label)

def switch():
    if lbl.cget('bg') == 'blue':
        lbl.config(bg='black')
    else:
        lbl.config(bg='blue')
    lbl.after(2000, switch)

This works fine. However, I want to be able to call switch for any label rather than just lbl specifically.

If I try the below I immediately get a recursion depth error

def switch(i):
    if i.cget('bg') == 'blue':
        i.config(bg='black')
    else:
        i.config(bg='blue')
    i.after(2000, switch(i))
 
lbl.after(2000, switch(lbl))

I'm not sure why this is a the case, or what I could do to get round it so any help would be appreciated!!!



Solution 1:[1]

You can pass positional arguments to after. To run switch(i) after 2 seconds you can call after like this, adding the positional arguments after the function:

i.after(2000, switch, i)

Likewise, to run switch(lbl) do this:

lbl.after(2000, switch, lbl)

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 Bryan Oakley