-1

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!!!

  • You need a `lambda` statement. Try `lambda: switch(i)` instead of just `switch(i)`. Similar to/duplicate of [this question](https://stackoverflow.com/q/5767228/16775594). – Sylvester Kruin Feb 16 '22 at 22:10
  • That makes so much sense. Just so I have it right then: After() requires the name of a function to be called by itself. Prefixing the function I want to call with lambda: effectively wraps the full function in a single name that after() can recognise? – Pelmichr Feb 16 '22 at 22:18
  • @SylvesterKruin: you don't _need_ lamda, it's just one possible solution. – Bryan Oakley Feb 16 '22 at 22:26
  • @BryanOakley I hadn't heard of any other solutions until I saw your answer. I'll remember in the future! – Sylvester Kruin Feb 16 '22 at 22:53

1 Answers1

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)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685