0

I have this simple tkinter code:

from tkinter import *

listofwordstodisplay = ['apple', 'banana', 'kiwi', 'pear']
def word(idx):
    return listofwordstodisplay[idx]

root=Tk()
root.geometry("400x200")
root.configure(bg='white')

label=Label(root)

label.pack(anchor=CENTER, expand=TRUE)
label.configure(text=word(2))
sleep(2)
label.configure(text=word(3))
root.mainloop()

It only shows word(3) which is 'pear'. How can I make it show word(2), wait 2 seconds, then show word(3)?

Simd
  • 19,447
  • 42
  • 136
  • 271

1 Answers1

1

Using only tkinter, you can take advantage of the Tk.after method, eg.

import time
import threading
import tkinter as tk

words = ['apple', 'banana', 'kiwi', 'pear']

def refresh_label(label, word):
    label.configure(text=word)

root = tk.Tk()
root.geometry("400x200")
root.configure(bg='white')

label = tk.Label(root)
label.pack(anchor=tk.CENTER, expand=tk.TRUE)

for i, word in enumerate(words):
    # binding word required because of the loop
    label.after(1000 * i, lambda w=word: label.configure(text=w))

root.mainloop()

You can also use something like threads to run code in parallel without blocking the UI main loop:

Tkinter is not thread-safe, you would need to delegate UI updates to the UI thread itself, for instance using a pub/sub system, see https://stackoverflow.com/a/54374873/1812262

michaeldel
  • 2,204
  • 1
  • 13
  • 19
  • 2
    Saying you _must_ use something like threads is not true. What the OP wants can easily be done without threads or multiprocessing of any sort. – Bryan Oakley Jan 30 '21 at 19:29
  • You can indeed use the `Tk.after` method, I forgot about it. I am editing my answer – michaeldel Jan 30 '21 at 19:32
  • 1
    Besides not needing to use multithreading, `tkinter` isn't thread-safe, so updating the GUI from different ones is likely to cause problems. – martineau Jan 30 '21 at 19:33
  • after looks really helpful thank you. I will try it out asap. – Simd Jan 30 '21 at 21:30