2016-01-15 53 views
0

所以,我對Python很新,但是一旦將它們放入類中,我就無法處理這些變量。Python 3.5中GUI的用戶輸入

下面的代碼工作正常,在沒有外部對象,但一旦我添加它,我得到的錯誤:

NameError: name 'someName' is not defined 

其中3號線

text = "You have entered " + someName.get() 

這裏發生的代碼:

class GUI: 
    def changeLabel(): 
     text = "You have entered " + someName.get() 
     labelText.set(text) 
     someName.delete(0, END) 
     someName.insert(0, "You've clicked!") 
     return 

    app = Tk() 
    app.title("GUI Test") 
    app.geometry('450x300') 

    labelText = StringVar() 
    labelText.set("Click when ready") 
    label1 = Label(app, textvariable=labelText, height=4) 
    label1.pack() 

    userInput = StringVar(None) 
    someName = Entry(app, textvariable=userInput) 
    someName.pack() 

    button1 = Button(app, text="Click Here", width=20,command=changeLabel) 
    button1.pack(side='bottom',padx=15,pady=15) 

    app.mainloop() 

GUI #calling the class to run 

任何幫助將不勝感激。

+0

'GUI #calling的類run'都能跟得上你的Tkinter的引用。這不是你稱之爲的方式。請先檢查python類教程。 – Lafexlos

+0

這裏有很多問題。您應該重讀'TKinter'教程。 –

+0

另外,你應該在你的問題中描述你期望你的代碼做什麼。 –

回答

0

您的GUI類的格式不正確。你不應該把代碼轉儲到一個類中,它應該在一個方法中(一個屬於一個類的函數)。對於像這樣的東西,通常的做法是將其放入__init__方法中,該方法在通過調用類創建類的實例時自動調用。

方法可以有自己的局部變量,也可以使用self.attribute_name語法訪問實例的屬性。你的NameError: name 'someName' is not defined錯誤信息是因爲Python認爲someName是一個局部變量changeLabel,它並沒有意識到它應該是你的Entry小部件。

無論如何,我修復了你的代碼,以便它運行;大概它按照你的意圖做了。請注意,這些方法有self作爲它們的第一個參數。請閱讀關於類的一些Python文檔/教程以獲取更多信息。

from Tkinter import * 

class GUI(object): 
    def changeLabel(self): 
     text = "You have entered " + self.someName.get() 
     self.labelText.set(text) 
     self.someName.delete(0, END) 
     self.someName.insert(0, "You've clicked!")    

    def __init__(self): 
     app = Tk() 
     app.title("GUI Test") 
     app.geometry('450x300') 

     self.labelText = StringVar() 
     self.labelText.set("Click when ready") 
     label1 = Label(app, textvariable=self.labelText, height=4) 
     label1.pack() 

     userInput = StringVar(None) 
     self.someName = Entry(app, textvariable=userInput) 
     self.someName.pack() 

     button1 = Button(app, text="Click Here", width=20,command=self.changeLabel) 
     button1.pack(side='bottom',padx=15,pady=15) 

     app.mainloop() 

GUI() #calling the class to run 

此代碼適用於Python 2;您需要將Python 3上的import聲明更改爲from tkinter import *。其實,不建議使用import *,因爲它會污染你的名字空間和所有導入的名字。這是更好地做類似

import tkinter as tk 

,然後寫出這樣

app = tk.Tk() 

label1 = tk.Label(app, textvariable=self.labelText, height=4) 

+0

謝謝。我意識到它不是靠近像樣的Python代碼的地方,我看過的教程沒有像上面那樣進入設置的類和方法。我想我將不得不盡快挖掘一些好的教程。 – coelicasi

+0

@ coelicasi:沒問題。'import *'模式在示例代碼(甚至是官方文檔/教程)中很常見,因爲它使得代碼更加冗長,但不幸的是,它給了人們一個很好的做法。您可以在沒有將代碼組織到類中的情況下執行簡單的GUI工作,但當您嘗試構建複雜的GUI時,它很快就會變得雜亂無章。除了查看教程之外,在這裏還有很多很棒的示例代碼,儘管有時候甚至專家也會使用'import *'模式來保持簡單。 –

0

你在代碼中有一些錯誤,並沒有以你應該的方式使用類。我修改了代碼並評論了新行,以便了解發生的事情。我已經爲所有文本變量添加了self引用,以便它們可以正確訪問。

from tkinter import * 

class GUI: 
     #set these so that they are able to be used by the whole class 
     labelText = "" 
     userInput = "" 

     #you should have an init method for your classes and do all the setup here 
     def __init__(self,master): 
       self.labelText = StringVar() 
       self.userInput = StringVar() 

       #you should pack things into a frame 
       frame = Frame(master)  
       frame.pack() 

       self.labelText.set("Click when ready") 
       label1 = Label(frame, textvariable=self.labelText, height=4) 
       label1.pack() 

       someName = Entry(frame, textvariable=self.userInput) 
       someName.pack() 

       button1 = Button(frame, text="Click Here", width=20,command=self.changeLabel) 
       button1.pack(side='bottom',padx=15,pady=15) 

     def changeLabel(self): 
       text = "You have entered " + self.userInput.get() 
       self.labelText.set(text) 
       self.userInput.set("You've clicked!") 
       return 

#create the app before you call the GUI. 
app = Tk() 
app.title("GUI Test") 
app.geometry('450x300') 

# when you create the class, you need to assign it to a variable 
applet = GUI(app) #calling the class to run 
app.mainloop()