Sleep()会停止线程

时间:2015-08-30 17:18:14

标签: python tkinter

我正在尝试运行一个使用root.after()生成几个线程的脚本。 sleep()似乎锁定了脚本。它永远不会看到第二个root.after()。

设置了Flag
from 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')

2 个答案:

答案 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中设置任何动画,例如在屏幕上移动小部件或定期更改颜色。