无法调用函数更改stringvar

时间:2019-03-15 06:02:03

标签: python tkinter

我正在尝试通过更改tkinter标签并使用Time Module来创建一个小时钟。我无法弄清楚如何使用while循环调用test()函数,因为我不断遇到未定义timee或未定义test()的错误。有什么我想念的吗?

import time
from tkinter import *

def test():
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)

while 1 > 0:
    test()

root = Tk()
timee = StringVar()

l = Label(root, textvariable=timee)
l.pack(side=TOP)

root.mainloop()

3 个答案:

答案 0 :(得分:1)

如果您想象程序从上到下运行,则永远不会到达创建TkStringVarLabel对象的位置;因为它陷入了无限while循环中。您收到的错误是因为调用test时,timee尚未定义。

简单地说,您的程序一次只能做一件事。当它忙于运行时钟时,它无法创建TKinter窗口。 OTOH,它正在管理tkinter窗口(.mainloop功能)时,无法更新您的时钟。

您需要让两者都玩得开心。 Tkinter对象有一种特殊的方法来告诉您您想要完成某件事:after。 (请参见tkinter Widget docs):

import time
from tkinter import *

def test():
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)
    # after updating, schedule next call in 1 second
    root.after(1000, test)

root = Tk()
timee = StringVar()

l = Label(root, textvariable=timee)
l.pack(side=TOP)

# Before starting up, instruct Tkinter to run test after 1 second
root.after(1000, test)
root.mainloop()

如您所见,test()不再有明确的调用。相反,在after()中,测试函数作为变量传递。您可以考虑将after()的指令列表交给他们,而无需执行它们。

然后,当tkinter运行其窗口(.mainloop()调用)时,它将查看其待办事项列表,并找到您订购的test调用。在正确的时间,它将一次调用test函数;然后在函数结束时,安排下一个调用。

答案 1 :(得分:0)

timee未定义,因为您的函数正在寻找本地var timee,但是您想更改全局变量,因此需要在函数中指示它

def test():
    global timee
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)

答案 2 :(得分:0)

Tkinter应用程序由用户驱动,这意味着常规的程序编程技术通常不起作用-所有处理都必须在mainloop()运行时进行。

在这种情况下,您可以使用通用窗口小部件方法after{}定期安排对测试函数的调用,例如每秒 1 / 4 250毫秒):

import time
from tkinter import *

def test():
    seconds = time.time()
    local_time = time.ctime(seconds)
    timee.set('The Time Is: ' + local_time)

def poll():
    test()
    root.after(250, poll)  # Schedule another call.

root = Tk()
timee = StringVar()

l = Label(root, textvariable=timee)
l.pack(side=TOP)

poll()  # Start periodic calls to test()
root.mainloop()