2013-07-13 50 views
1

我已經寫了一些python計時器的代碼,但是當我運行它時,我得到一個錯誤,但事情是我不知道該怎麼做,因此我搜索了所有後來到這裏尋求幫助互聯網的幫助,但我找不到任何符合我的問題。tkinter的基本計時器

以下是錯誤:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Program Files\Python33\lib\tkinter\__init__.py", line 1475, in __call__ 
    return self.func(*args) 
    File "C:\Users\Public\Documents\Programming\Timer.py", line 27, in start 
    sec = sec + 1 
UnboundLocalError: local variable 'sec' referenced before assignment 

這是我的代碼:

# Import Modules 
from tkinter import * 
import time 

# Window Setup 
root = Tk() 
root.title('Timer') 
root.state('zoomed') 

# Timer Variables 
global sec 
time_sec = StringVar() 
sec = 0 

# Timer Start 
def start(): 
    while 1: 
     time.sleep(1) 
     sec = sec + 1 
     time_sec.set(sec) 
     start() 

# Timer Setup 
Label(root, 
     textvariable=time_sec, 
     fg='green').pack() 
Button(root, 
     fg='blue', 
     text='Start', 
     command=start).pack() 

# Program Loop 
root.mainloop() 

任何人都可以幫我嗎?

在此先感謝!

回答

4

您必須聲明sec是的start一個全球性的內部。以下是如何修正錯誤:

# Import Modules 
from tkinter import * 
import time 

# Window Setup 
root = Tk() 
root.title('Timer') 
root.state('zoomed') 

# Timer Variables 
global sec 
time_sec = StringVar() 
sec = 0 

# Timer Start 
def start(): 
    while 1: 
     time.sleep(1) 
     ### You have to declare sec as a global ### 
     global sec 
     sec = sec + 1 
     time_sec.set(sec) 
     start() 

# Timer Setup 
Label(root, 
     textvariable=time_sec, 
     fg='green').pack() 
Button(root, 
     fg='blue', 
     text='Start', 
     command=start).pack() 

# Program Loop 
root.mainloop() 

然而,這仍然有問題,因爲它凍結屏幕由於while循環。一個更好的辦法來建立與Tkinter的計時器是這樣的:

from tkinter import * 

root = Tk() 
root.title('Timer') 
root.state('zoomed') 

sec = 0 

def tick(): 
    global sec 
    sec += 1 
    time['text'] = sec 
    # Take advantage of the after method of the Label 
    time.after(1000, tick) 

time = Label(root, fg='green') 
time.pack() 
Button(root, fg='blue', text='Start', command=tick).pack() 

root.mainloop() 

此外,一些建議爲未來:從未使用time.sleepwhile循環一樣,在一個GUI。代之以利用GUI的主循環。這將節省許多頭痛的東西凍結或崩潰。希望這可以幫助!

+0

我非常感謝關於使用'after'方法的提示,因爲它應該更高效並且可能更準確;但是,您可以使用事件來防止凍結和崩潰,同時仍然使用'sleep'保持'while'循環。我實際上做了這樣一個計時器,但是我不知道'after'方法,那麼。我希望轉換到它將允許更小的間隔。 – Shule

0

你必須發起global sec在start.ie:

...... 
# Timer Start 
def start(): 
    global sec 
    ..... 

您可以在class放在裏面。這樣你就不用擔心變量的作用域..

from tkinter import * 
import time 

class App(): 
    def __init__(self): 
     self.window = Tk() 
     self.root = Frame(self.window, height=200,width=200) 
     self.root.pack() 
     self.root.pack_propagate(0) 
     self.window.title('Timer') 
     self.label = Label(text="") 
     self.label.pack() 
     self.sec = 0 
     self.timerupdate() 
     self.root.mainloop() 
    def timerupdate(self): 
     self.sec = self.sec + 1 
     self.label.configure(text=self.sec) 
     self.root.after(1000, self.timerupdate) 

app=App() 
app.mainloop() 
+1

如果您提供了有關更改的文字說明,那麼您的答案會更有用。否則,讀者將被迫逐行嘗試找出你改變了什麼,或者OP的代碼不起作用的主要原因是什麼。 –

+0

有沒有辦法讓自己做到這一點? – Elxafil