2014-11-24 63 views
0

如何使定時器在Canvas中更新?Tkinter GUI秒錶/定時器

create.text(position, **options)默認位置,可以用anchor=tk.CENTER理應覆蓋,但我得到一個:

NameError: name 'tk' is not defined

,如果我嘗試添加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() 

如果我mainloop()畫布沒有啓動之前把Run()。在mainloop()Run()未啓動後。

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

+0

無限'while'循環使Tkinter鎖定。考慮使用'Tk.after'來代替。 – Kevin 2014-11-24 19:30:03

+1

另外,如果你需要回答兩個單獨的問題,「爲什麼我會得到一個NameError?」,這可能是值得的。和「我如何定期更新計時器?」 – Kevin 2014-11-24 19:31:45

回答

3

這條線:

from Tkinter import * 

將所有從Tkinter的庫的名字進入全球namspace。所以,你可以直接訪問它們:

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

你會只做tk.CENTER了您導入Tkinter的,如:

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_textRun函數中,使其與中Run每次調用更新。請注意,在添加新文本之前,您需要先撥Canvas.delete,以便刪除任何舊文本。