Rt Rtt
Rt Rtt

Reputation: 617

How to use Tkinter after() method?

I have a problem using the after method in Tkinter.

The plan is to print i with interval of one second. I checked whether the after method is suitable, but I don't know exactly.

Here is the code.

# -*- coding: utf-8 -*-

from Tkinter import *
import time

root = Tk()
root.title("Program")
root['background'] ='gray'

def command_Print():
    for i in range(0, 10, 1):
        time.sleep(1)
        Label0.after(1)
        Labelvar.set(i)

Labelvar = StringVar()
Labelvar.set(u'original value')
Frame0 = Frame(root)
Frame0.place(x=0, y=0, width=100, height=50)
Label0 = Label(Frame0, textvariable=Labelvar, anchor='w')
Label0.pack(side=LEFT)


Frame_I = Frame(root)
Frame_I.place(x = 100, y = 0, width=100, height=70)
Button_I = Button(Frame_I, text = "Button" , width = 100, height=70, command = command_Print)
Button_I.place(x=0, y=0)
Button_I.grid(row=0, column=0, sticky=W, pady=4)
Button_I.pack()

root.mainloop()

Upvotes: 3

Views: 12156

Answers (2)

Bryan Oakley
Bryan Oakley

Reputation: 385930

after with a single argument (eg: after(10)) is the same as calling time.sleep, and should generally be avoided. Since it puts your GUI to sleep, your GUI won't be able to respond to any events (including requests by the user or OS to refresh or resize the window)

When you call after with two or more arguments, the second argument is a reference to a function you want to call in the future. All remaining arguments will be passed to that function.

Tkinter maintains a queue of events. mainloop is the function that watches that queue and runs events as they come in. When you call after, the function you requested is simply added to the queue with a timestamp. When it is ready to be processed, tkinter will call the function and pass in the arguments. It's as simple as that.

Upvotes: 7

TigerhawkT3
TigerhawkT3

Reputation: 49318

Don't use time.sleep() at all in Tkinter applications. Have the callback schedule a call to itself with after().

def command_Print(counter=0):
    Labelvar.set(counter)
    if counter < 10:
        root.after(1000, lambda: command_Print(counter+1))

Also, range(0, 10, 1) is just range(10). There's no need to repeat the defaults.

Upvotes: 4

Related Questions