-1

I'm trying to update the text of a label from a Thread but it doesn't work. Here is a sample of the code

def search_callback():
    class Holder(object):
        done = False

    holder = Holder()
    t = threading.Thread(target=animate, args=(holder,))
    t.start()
    #long process here
    holder.done = True   # inform thread long process is finished

def animate(holder):
    for c in itertools.cycle(['|', '/', '-', '\\']):
        if holder.done:
            break
        print('\rRecherche ' + c)   # This work!
        label_wait.configure(text='\rRecherche ' + c)  # this doesn't work nothing appear in my label
        time.sleep(0.5)
    label_wait.configure(text='\rTerminé!     ')
    print('\rTerminé!  ')

But I don't understand why the label_wait.configure doesn't work also print works well.

I've tried to use after method in my thread but it's doesn't change.

simon
  • 1,180
  • 3
  • 12
  • 33
  • What do you mean by "it doesn't work"? Are you getting an error message, is the label not being updated, ...? – muhmann Feb 27 '23 at 08:53
  • the label is not being update, nothing appear @muhmann – simon Feb 27 '23 at 08:54
  • 1
    Tkinter has a [different threading model](https://docs.python.org/3/library/tkinter.html#threading-model) – Emanuel P Feb 27 '23 at 09:02
  • Does this answer your question? [Python - Tkinter - Label Not Updating](https://stackoverflow.com/questions/39637493/python-tkinter-label-not-updating) – DerSchinken Feb 27 '23 at 09:05
  • You should run the *long process* in a thread and run the *animation* using `.after()`. – acw1668 Feb 27 '23 at 10:15
  • I would do the same as @acw1668 but you should keep in mind that your running thread keeps running if you close the window. So maybe take a second and think about correctly ending your threads in case you exit tkinter during your loop. You should bind WM_DELETE_WINDOW to a closing method `self.root.protocol("WM_DELETE_WINDOW", self._on_closing)` – Ovski Feb 27 '23 at 14:02
  • Post a [mre]. How the ```label_wait``` is created and shown? Also the ```holder.done``` is changed to ```True``` immediately after ```t.start()```. And you need to change the UI in the main thread via ```after_idle()``` to minimize a side effect. See [this answer](https://stackoverflow.com/a/74989468/1186624). – relent95 Feb 27 '23 at 14:39

1 Answers1

0

Thread but it doesn't work

Don't worry about Thread

  • Change to False to holder.done = False
  • Removed label_wait.configure(text='\rTerminé! ') and print()

`

Snippet:

import tkinter as tk
import itertools
import time
import threading

root = tk.Tk()

def search_callback():
    class Holder(object):
        done = False

    holder = Holder()
    t = threading.Thread(target=animate, args=(holder,))
    t.start()
    #long process here
    holder.done = False   # inform thread long process is finished

def animate(holder):
    for c in itertools.cycle(['|', '/', '-', '\\']):
        if holder.done:
            break
        print('f\rRecherche {c}')   # This work!
        label_wait.configure(text=f'\rRecherche {c}')  # this doesn't work nothing appear in my label
        time.sleep(0.5)
    
label_wait = tk.Label(root)
label_wait.pack()
search_callback()
root.mainloop()

Screenshot:

enter image description here

toyota Supra
  • 3,181
  • 4
  • 15
  • 19