0

I like to create an object per second and make the show up one by one. However, the code below wait for 3 seconds and show them all at the same time.

from tkinter import *
import time
def create():
   for i in range(3):
      r4=Radiobutton(root, text="Option 1"+str(i), value=1)
      r4.pack( anchor = W )
      time.sleep(1)
root = Tk()
create()
root.mainloop()
  • sleep doesn't work well with tkinter's mainloop. You should check out [after method](https://stackoverflow.com/questions/25753632/tkinter-how-to-use-after-method). – Lafexlos Jun 12 '17 at 20:25

2 Answers2

0

You can use update to call a refresh on your objects.

In use, you would have to add the line root.update() in your for loop.

SneakyTurtle
  • 1,831
  • 1
  • 13
  • 23
  • Hi @TimoThund if this answer has solved your question please consider [accepting it](https://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. **Of course, there is no obligation to do this.** – Lafexlos Jun 12 '17 at 20:22
0

Your code, as is, creates a one object per second as you desired it, but this objects need to be shown, and they're shown when code flow reaches the mainloop. Hence, for observer, it looks like there're no objects at all after one second.

Of course, you can use sleep and update, but beware - sleeping leads to unresponsive window, so it's OK option (to be honest - not OK at all), if your application isn't drawn and you're outside of mainloop, but if it's not - prepare for a "frozen" window, because GUI can redraw himself only in mainloop (an event loop, you can reach it with update as well) and sleep blocks this behaviour.

But there's a good alternative, the after method, take a look on it!

And there's a snippet, so you can see the difference:

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk
import time

def create_with_sleep():
    for _ in range(3):
        tk.Radiobutton(frame_for_sleep, text="Sleep Option").pack(anchor='w')
        time.sleep(int(time_entry.get()))
        root.update()

def create_with_after(times=3):
    if times != 0:
        tk.Radiobutton(frame_for_after, text="After Option").pack(anchor='w')
        times -= 1
        root.after(int(time_entry.get()) * 1000, lambda: create_with_after(times))

root = tk.Tk()

test_yard_frame = tk.Frame(root)
frame_for_sleep = tk.Frame(test_yard_frame)
frame_for_after = tk.Frame(test_yard_frame)
test_yard_frame.pack()
frame_for_sleep.pack(side='left')
frame_for_after.pack(side='left')

button_frame = tk.Frame(root)
button_for_sleep = tk.Button(button_frame, text='Create 3 radiobuttons with sleep+update', command=create_with_sleep)
button_for_after = tk.Button(button_frame, text='Create 3 radiobuttons with after', command=create_with_after)
button_frame.pack()
button_for_sleep.pack(side='left')
button_for_after.pack(side='left')

time_label = tk.Label(root, text='Time delay in seconds:')
time_label.pack(fill='x')
time_entry = tk.Entry(root)
time_entry.insert(0, 1)
time_entry.pack(fill='x')

root.mainloop()

With 1 seconds delay there's no much difference, but you can try to increase delay to understand why after option is preferable in general.

CommonSense
  • 4,232
  • 2
  • 14
  • 38