Python tkinter在循环中更改stringvar,但不影响窗口
当我按下tk中的按钮时,我想每秒更改一次标签:Python tkinter在循环中更改stringvar,但不影响窗口,python,tkinter,Python,Tkinter,当我按下tk中的按钮时,我想每秒更改一次标签: # --coding:utf-8 ----- from Tkinter import * import time import random def test(a): begin =time.time() end =time.time() while True: ran = random.random() after = time.time() if(after-begin
# --coding:utf-8 -----
from Tkinter import *
import time
import random
def test(a):
begin =time.time()
end =time.time()
while True:
ran = random.random()
after = time.time()
if(after-begin >1):
a.set(str(ran))
print a.get()
begin =after
if(after-end>10):
a.set('over')
break
t = Tk()
a = StringVar()
a.set('0')
b = Label(t,textvariable = a)
b.pack()
Button(t,text ='test',command = lambda x=a:test(a)).pack()
t.mainloop()
我的控制台输出是正确的,但对windows没有影响。为什么?您可以在单独的线程中启动test()函数,如下所示:
# --coding:utf-8 -----
from Tkinter import *
import time
import random
import threading
def startThread(a):
threading.Thread(target=test, args=(a,)).start()
def test(a):
begin =time.time()
end =time.time()
while True:
ran = random.random()
after = time.time()
if(after-begin >1):
a.set(str(ran))
print a.get()
begin =after
if(after-end>10):
a.set('over')
break
t = Tk()
a = StringVar()
a.set('0')
b = Label(t,textvariable = a)
b.pack()
Button(t,text ='test',command = lambda x=a:startThread(a)).pack()
t.mainloop()
然而,即使关闭窗口,线程也要到10秒结束时才会结束。您需要为
while
循环找到一些代码,以检查应用程序是否仍在运行。创建必须在给定时间段内执行的行为是一个常见问题;你可以通过一个专门的服务员课程来解决这个问题;这避免了使用tkinter
不支持的线程
下面的示例打开一个带有标签和按钮的窗口。按下按钮后,标签将在10秒内每秒钟更新一次,然后停止。
在10秒内再次按下按钮无效;之后,它会重新启动进程10秒以上
import Tkinter as tk # tkinter if python >= 3
import time
import random
class Waiter(object):
def __init__(self, waiting_time):
"""
:param waiting_time: int, in seconds
"""
self.waiting_time = waiting_time
self.expiring_time = time.time() + self.waiting_time
self.waiting = True
# print('waiter started')
def stop(self):
# print('waiter stopping')
self.expiring_time = None
self.waiting = False
def is_waiting(self):
"""returns True while waiting, false otherwise"""
if time.time() > self.expiring_time:
self.stop()
return self.waiting
def atest():
global waiter
if waiter is None:
waiter = Waiter(10)
_atest()
def _atest():
""" equivalent to:
while the waiter is waiting,
change the label every second),
then destroy the waiter
"""
global waiter
if waiter.is_waiting():
a.set(random.random())
# print(time.time())
t.after(1000, _atest)
else:
waiter = None
if __name__ == '__main__':
waiter = None
t = tk.Tk()
a = tk.StringVar()
a.set('0')
tk.Label(t, textvariable=a).pack()
tk.Button(t, text='test', command=atest).pack()
t.mainloop()
注:
您可以将\u atest
作为atest
的一个内部函数,但它可能更容易理解
使用import Tkinter as tk
而不是从Tkinter import*
中使用导入Tkinter as tk,可以防止名称空间混乱,并可以使代码更清晰。
您可能应该考虑使用Python 3。