2013-06-20 51 views
0

我剛剛學習Python的TKinter模塊,並有一個簡單的文本框,要求速度和時間以及打印距離。出於某種原因,我的距離總是隨着時間的變化而變化。我想我要麼需要第二個條目或全球化我的變數,但是我想知道你Python Tkinter變量沒有被重新評估

from Tkinter import * 

master = Tk() 
speed = 10; time = 10; d = 50 
e = Entry(master) 
e.pack() 
e. delete(0, END) 
e.insert(0, "Enter Speed") 

def callspeed(): 
     s = e.get()  
     speed = int(s) 
     e.delete(0, END) 
     e.insert(0, "Enter time") 

def calltime(): 
     t = e.get() 
     time = int(t) 
     d = speed * time 
     print d 

bs = Button(master, text="Speed", width=15, command=callspeed) 
bs.pack() 
bt = Button(master, text="Time", width=15, command=calltime) 
bt.pack() 

mainloop() 

回答

1

的問題是什麼,這條線在callspeed

speed = int(s) 

創建一個新的本地變量稱爲speed,而不是更新全局變量。

要解決它,你只需要一個global聲明:

def callspeed(): 
    global speed 
    s = e.get()  
    speed = int(s) 
    e.delete(0, END) 
    e.insert(0, "Enter time") 

的確切規則有點複雜(「自由變量」 - 這基本上意味着你引用變量,但從未分配到可以從何而來一個閉包或全局變量;你分配給的變量總是本地的),但是要做的安全的事情是當你想使用一個全局變量時總是添加一個global語句。


或者,甚至更安全,首先不要使用全局變量。例如,您可以將所有這些代碼或其中的「模型」部分移動到類中,並使speed爲實例變量。

class ThingyModel(object): 
    def __init__(self, e): 
     self.speed, self.time, self.d = 10, 10, 50 
     self.e = e 

    def callspeed(self): 
     s = self.e.get() 
     self.speed = int(s) 
     self.e.delete(0, END) 
     self.e.insert(0, "Enter time") 

    def calltime(self): 
     t = self.e.get() 
     self.time = int(t) 
     self.d = self.speed * self.time 
     print d 

e = Entry(master) 
e.pack() 
e. delete(0, END) 
e.insert(0, "Enter Speed") 

model = ThingyModel(e) 

bs = Button(master, text="Speed", width=15, command=model.callspeed) 
bs.pack() 
bt = Button(master, text="Time", width=15, command=model.calltime) 
bt.pack() 

(這是不是一個真正的MVC設計,這是因爲「控制器」部分散落各地,而「意見」沒有組織成任何類型的結構,但應足以顯示的基本思路。)

+1

+1,但我覺得我應該提到這是經常可以看到的Tkinter類從像'Tkinter.Frame'其中小部件邏輯內保持和繼承只有'Tkinter.Tk()'的一個實例被傳遞給'__init__'。 – Jared

+0

@Jared:是的,我開始對整個事情進行pythonic/tkinteric清理,同時展示MVC設計和傳統Tkinter「智能視圖」設計......但後來我認定這種方法已經走上正軌。你的評論是一個很好的指針,不需要一個大的例子。 – abarnert

0

abarnert是對的,全局變量很混亂。這裏是我的速度和時間,本地變量重寫:

from Tkinter import * 

master = Tk() 
Label(master,text="Speed:").grid(row=0,column=0) 
Label(master,text="Time:").grid(row=1,column=0) 
speed_entry = Entry(master) 
speed_entry.grid(row=0,column=1) 
time_entry = Entry(master) 
time_entry.grid(row=1,column=1) 

def submit(): 
    speed = float(speed_entry.get()) 
    time = float(time_entry.get()) 
    print "Speed is",speed 
    print "Time is", time 
    print "Distance is",speed*time 

Button(master,text="Submit",command=submit).grid() 

master.mainloop() 
+0

這可能是一個比OP更好的UI和更好的設計......但它並不等同於OP,並沒有顯示如何解決需要兩個功能之間持續狀態的問題 - 這是一個最真實的問題GUI需要解決。 – abarnert