我正在尝试运行一个使用root.after()生成几个线程的脚本。 sleep()似乎锁定了脚本。它永远不会看到第二个root.after()。
设置了Flagfrom time import sleep
from tkinter import *
global Flag
Flag = False
def setTimer():
global Flag
while(Flag==False):
sleep(.1)
print('Flag set')
return
def setFlag():
global Flag
Flag=True
return
root=Tk()
print('Start')
root.after(1,setTimer())
root.after(100,setFlag())
print('Done')
答案 0 :(得分:3)
after
没有启动新线程,它在Tk的事件循环中运行一个方法。所以你的while循环总是会阻止程序。
如果使用after
,则该方法必须仅执行非阻塞操作,例如检查标志。如果您有后台进程,请使用实际线程。但请注意:你不能改变这些线程中的GUI!
import tkinter as tk
from time import sleep
from threading import Thread, Event
flag = Event()
def worker():
while not flag.is_set():
sleep(.1)
print('Flag set')
def set_flag():
flag.set()
root = tk.Tk()
print('Start')
Thread(target=worker).start()
root.after(100, set_flag)
print('Done')
root.mainloop()
答案 1 :(得分:0)
从您的示例中不清楚您是否确实需要OS线程或仅仅是异步事件驱动的任务。丹尼尔回答了前者,所以我会回答后者。关键是要完成一项任务“睡眠”。调用root.after而不是time.sleep。 (请注意,global name
只是需要的,并且只应在重新绑定name
的函数中使用。)
from tkinter import *
flag = False
def setTimer():
if flag:
print('Flag set')
else:
print('Flag not set')
root.after(100, setTimer)
def setFlag():
global flag
print('Setting flag')
flag=True
root=Tk()
print('Start')
root.after(1,setTimer)
root.after(300,setFlag)
root.mainloop()
这打印'标记未设置'三次,1,101和201毫秒,但在301毫秒,打印'标志设置'代替。 (时间不准确,但顺序应该是。)
Start
Flag not set
Flag not set
Flag not set
Setting flag
Flag set
重复后的技巧是如何在tkinter中设置任何动画,例如在屏幕上移动小部件或定期更改颜色。