我有一个更高级的代码,但这一切都来自这个简单的例子:
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()
在这个简单的例子中,我想启动sendData函数,它将在每次循环迭代时相应地更新printOut Label。我们都知道它没有,它会挂起,直到功能完成,并打印最后一个数字(5)。
我尝试了无数的线程和排队示例,而且我的失败很严重。 请简单澄清这个例子,当你需要在另一个线程中执行Tkinter元素时,如何正确地进行线程化。
我真的很沮丧,我在这一步花了最后两天......
答案 0 :(得分:2)
您必须添加update_idletasks()才能更新标签。而不是销毁和创建,只需更新文本,并在Tkinter中使用after()而不是sleep,因为它会生成一个新进程,而time.sleep()会在睡眠时挂起程序。
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()