sale1902
sale1902

Reputation: 117

Threading with Tkinter done right (with or without queues)

i have a much more advanced code, but it all comes to this simple example:

from Tkinter import *
import time

def destroyPrint():
    global printOut
    try:
        printOut.destroy()
    except:
        pass


def sendData():
    global new
    global printOut
    for i in range(6):
        destroyPrint()
        time.sleep(1)
        printOut=Label(new,text=i,font=('arial',15,'bold'))
        printOut.place(x=300,y=500)


def newWindow():
    global new
    print("ok")
    new=Toplevel()
    new.minsize(800,600)
    functionButton=Button(new,text="Send me",width=20,height=20, command=sendData)
    functionButton.place(x=300,y=150)


main = Tk()
main.minsize(800, 600)
menu=Button(main,text="Send data",width=20,height=20, command=newWindow)
menu.place(x=300,y=150)
mainloop()

In this simple example, i want to start sendData function, which will update printOut Label accordingly on every loop iteration. We all know that it doesn't, and that it hangs, until function is done, and prints last number (5).

I tried countless examples with threading and queueing, and i am failing badly. Please, just simple clarification on this example, how to do threading correctly when you have Tkinter elements in a function that needs to be performed in another thread.

I am really getting frustrated here and i spent last 2 days on this step...

Upvotes: 0

Views: 395

Answers (1)

user2133443
user2133443

Reputation: 171

You have to add update_idletasks() to update the label. Instead of destroying and creating, just update the text , and use after() in Tkinter instead of sleep as it spawns a new process whereas time.sleep() hangs the program while sleeping.

from Tkinter import *
import time

def sendData():
    global new
    ##global printOut
    printOut=Label(new,text="0",font=('arial',15,'bold'))
    printOut.place(x=300,y=500)
    for x in range(6):
        ##destroyPrint()
        printOut.config(text=str(x))
        new.update_idletasks()
        time.sleep(1)

def newWindow():
    global new
    print("ok")
    new=Toplevel()
    new.minsize(800,600)
    functionButton=Button(new,text="Send me",width=20,
                  height=20, command=sendData)
    functionButton.place(x=300,y=150)


main = Tk()
main.minsize(800, 600)
menu=Button(main,text="Send data",width=20,height=20, command=newWindow)
menu.place(x=300,y=150)
main.mainloop()

Upvotes: 2

Related Questions