2014-11-24 5 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() 

Если я ставлю перед тем Run()mainloop() Холст не запускается. После того, как mainloop() и Run() не запустится.

mainloop(Run()) и Run() начинается до Canvas.

+0

Бесконечные циклы 'while' заставляют Tkinter блокироваться. Вместо этого используйте 'Tk.after'. – Kevin

+1

Кроме того, может возникнуть вопрос задать два отдельных вопроса, если вам нужен ответ «почему я получаю« NameError »? и «как я периодически обновляю таймер?» – Kevin

ответ

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!"


Что касается второй части вашего вопроса, вы не можете использовать while True: или time.sleep в том же потоке, что и цикл обработки событий Tkinter работает в Doing либо из них будет блокировать 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, прежде чем добавлять новый текст, чтобы удалить старый текст.