Tkinter GUI秒表/计时器

时间:2014-11-24 19:26:52

标签: python canvas tkinter

如何在Canvas

中更新计时器

create.text(position, **options)中,可以使用anchor=tk.CENTER覆盖默认位置,但我得到了:

  

NameError:名称'tk'未定义

如果我尝试添加anchor选项。

import time
from Tkinter import *

run = True; s=0; m=0; h=0

def Run():
    global run, s, m, h
    while run == True:
        time.sleep(1)
        s+=1
        if s == 59:
            m+=1; s=-1
        elif m == 59:
            h+=1; m=-1

master = Tk()
w = Canvas(master, width=1500, height=800)
w.pack()

x.create_text(
    [750, 400], anchor=tk.CENTER, text="%s:%s:%s" % (s, m, h), font=("Consolas", 400)
    )

mainloop()

Run()

如果我在Run()之前放置mainloop(),则Canvas无法启动。 mainloop()Run()未启动后。

mainloop(Run())Run()Canvas之前开始。

1 个答案:

答案 0 :(得分:3)

这一行:

from Tkinter import *

将Tkinter库中的所有名称都带入全局namspace。所以,你可以直接访问它们:

x.create_text(
    ..., anchor=CENTER, ...
    )

如果你导入了Tkinter,你只会tk.CENTER

import Tkinter as tk

我必须说是一种更好的方法。通过执行from ... import *来混淆全局命名空间是一种不好的做法。请记住:

"Namespaces are one honking great idea -- let's do more of those!"


关于问题的第二部分,您不能在与Tkinter事件循环操作相同的线程中使用while True:time.sleep。执行其中任何一个操作都会阻止Tkinter循环并导致程序冻结。

相反,您可以使用Tk.after在后台执行Run

from Tkinter import *

run = True; s=0; m=0; h=0

def Run():
    global run, s, m, h

    # Delete old text
    w.delete('all')
    # Add new text
    w.create_text(
        [750, 400], anchor=CENTER, text="%s:%s:%s" % (s, m, h), font=("Consolas", 400)
        )

    s+=1
    if s == 59:
        m+=1; s=-1
    elif m == 59:
        h+=1; m=-1

    # After 1 second, call Run again (start an infinite recursive loop)
    master.after(1000, Run)

master = Tk()
w = Canvas(master, width=1500, height=800)
w.pack()

master.after(1, Run)  # after 1 millisecond, start Run
mainloop()

此外,我将调用移至Canvas.create_text函数内的Run,以便每次调用Run时都会更新。另请注意,您需要在添加新文本之前调用Canvas.delete,以便删除任何旧文本。