2016-11-15 5 views
0

Ich erstelle ein Dropdown-Menü mit tkinter. Es hat ein Untermenü "Datei" und einen Befehl "Öffnen" mit einem Eintrag, um dem Benutzer zu ermöglichen, den Pfad der Datei einzugeben, die sie öffnen möchten, und auf eine Schaltfläche zu klicken, um sie zu öffnen. Derzeit versuche ich get() zu verwenden, um den Eintrag Text abzurufen, wenn die Schaltfläche geklickt wird, wie weiter unten in meinem Code gezeigt:NameError mit Tkinter get()

# Assign 5 
from tkinter import * 

def getFile(): 
'Displays the text in the entry' 
print(E1.get()) 

def openFile(): 
'Creates enty widget that allows user file path and open it' 
win = Tk() 
#add label 
L1 = Label(win, text="File Name") 
#display label 
L1.pack() 
#add entry widget 
E1 = Entry(win, bd = 5) 
#display entry 
E1.pack(fill=X) 
#create buttons 
b1 = Button(win, text="Open", width=10, command = getFile) 
b2 = Button(win, text = "Cancel", width=10, command=win.quit) 
#display the buttons 
b1.pack(side = LEFT) 
b2.pack(side = LEFT) 

# create a blank window 
root = Tk() 
root.title("Emmett's awesome window!") 

#create a top level menu 
menubar = Menu(root) 
# add drop down "File" menu with command "Open" to the menubar 
fileMenu = Menu(menubar, tearoff=0) 
menubar.add_cascade(label="File", menu=fileMenu) 
fileMenu.add_command(label = "Open", command = openFile)  

# display the menu 
root.config(menu=menubar) 
root.mainloop() 

Aber ich erhalte den folgenden Fehler:

Exception in Tkinter callback 
Traceback (most recent call last): 
File  "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1550, in __call__ 
return self.func(*args) 
File "/Users/emmettgreenberg/Documents/2016/CS521/assign5/assign5_2.py", line 6, in getFile 
print(E1.get()) 
NameError: name 'E1' is not defined 

Von dem, was ich verstehe, muss ich nicht E1 als Argument übergeben, wenn ich getFile aufrufen. Wie kann ich das beheben?

Antwort

1

Da E1 eine lokale Variable innerhalb von openFile() ist, kann innerhalb von getFile() nicht darauf zugegriffen werden. Entweder Sie machen E1 global oder den Inhalt von E1 über getFile() passieren:

def getFile(filename): 
    print(filename) 

def openFile(): 
    ... 
    b1 = Button(win, text="Open", width=10, command=lambda: getFile(E1.get())) 
    ... 

Oder können Sie globale StringVar definieren, um die Dateinamen zu halten und es mit E1:

def getFile(): 
    print(filename.get()) 

def openFile(): 
    ... 
    E1 = entry(win, bd=5, textvariable=filename) 
    ... 

root = Tk() 
filename = StringVar() 

BTW, besser Änderung win = Tk() zu win = Toplevel() innerhalb openFile().

+0

Danke, ich habe Lambda verwendet, um den Dateinamen zu übergeben und es funktioniert, aber ich verstehe nicht, warum Lambda benötigt wird? Warum verwenden Sie auch ** Toplevel() ** anstelle von ** Tk() **? –

+0

@EmmettGreenberg Im Allgemeinen sollte eine tkinter App genau 1 Tk Master-Anwendungs-Widget haben. Mehr als eins zu haben, kann zu kleinen Fehlern führen. –

+0

Lambda wird verwendet, um alle im Rahmen der 'openFile()' - Funktion definierten Ressourcen an die 'getFile()' -Funktion zu übergeben. Mit 'Tk()' wird eine weitere Instanz des 'root'-Fensters initialisiert, die unabhängig vom ersten erstellten' root'-Fenster ist, aber 'Toplevel()' befindet sich innerhalb der Hierarchie des ersten 'root'-Fensters. Scheint, dass beide den gleichen Effekt haben können, aber die Bedeutungen sind unterschiedlich. – acw1668