[Tutor] Tkinter and after() method

Alan Gauld alan.gauld at yahoo.co.uk
Fri Jan 27 05:17:52 EST 2023


On 27/01/2023 06:10, Phil wrote:
> It's been quite some time since I've played with Tkinter and despite 
> searching the Internet for most of the day I seem to have hit a dead-end.
> 
> I'm trying to put a pause within a for-loop as follows:
> 
> def my_function(self):
>      for i in range(5):
>          do something here eg. print(i)
>          self.after(1000)
> 

It really helps if you show us working code. It need not
be your own application but just a simple model of your
code structure that exhibits the same behaviour.

In this case I assume the "functin" is actually a method
of your App or GUI or window object? (A method is not
the same as a fuction with a self parameter!)

If thats the case calling after inside a for loop is
extremely bad practice and quite likely to cause your
GUI to freeze which is a very bad user experience.

> Instead of printing i every second my_function is delayed for 5 seconds.

I'm not sure why because I don't see anything that
could be tested.

> To try to get some understanding of what's required I tried this:
> 
> self.r = 31
> 
> self.abc()
> self.print_count()
> self.after(1000, self.print_count()
> 
> def abc(self):
>      self.r += 1
>      print(self.r)
> 
> def print_count(self)
>      self.abc()
>      self.after(1000, self.print_count()

That makes no sense whatsoever.
What context did you try that in? Is it inside another method?
In which case your abc() and print_count() methods only exist
inside that method?

If you defined it somewhere else what does the outer
self refer to?

> This prints 32 - 1025, without a one second delay, before the programme 
> ends with: "RecursionError: maximum recursion depth exceeded while 
> calling a Python object".

No surprise on the error because print_count calls
print_count forever. Why there is no delay may depend
on the code we can't see.

> Although I haven't tried it I suspect that if I used a label to display 
> the count rather than a print statement then I might not see a recursion 
> error.

Yes you wouyld. You never terminate the recursion so
it will keep going till it reaches the limit.

I think you should try using after() in a more conventional
split-method way rather than continue with this approach.
It is almost certain to end badly.

Here is a simple program that does what I think you want:

import tkinter as tk

count = 0

def run_loop():
    global count
    if count < 5:
       count += 1
       print_count(count)
    else:
       count = 0

def print_count(val):
    print(val)
    top.after(1000, run_loop)

top = tk.Tk()
F = tk.Frame(top)
B = tk.Button(F, text="DoIt", command = run_loop)
B.pack()
F.pack()
top.mainloop()


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos





More information about the Tutor mailing list