0

For some reason, I cannot get my code to work — it shows me errors that the variable doesn't exist when it does.

Here is my code:

from tkinter import *
from tkinter import messagebox as msg
from tkinter import filedialog #https://pythonspot.com/tk-file-dialogs/
def save():
    global filename
    try: #here, if variable `filename' does not exist, we will ask for a filename. if it does exist, we'll use it. kind of like how a normal text editor makes you save as the same file until you click "New".
        yolo = filename
        del yolo
        keepTheFilename = True
    except:
        keepTheFilename = False
    from os.path import expanduser
    home = expanduser("~")
    if keepTheFilename is True:
        filename = filedialog.asksaveasfilename(initialdir=home, title="Saving file")
    #print("Saving to  %s" % filename, end="\r")
    theText = text.get(0.0, "end-1c") #https://stackoverflow.com/a/14824164/9654083
    with open(filename, "w") as theFile:
        theFile.write(theText)
        print("Saving to  %s, done." % filename)
    slate.title(filename)
def openFile():
    from os.path import expanduser
    home = expanduser("~")
    filename = filedialog.askopenfilename(initialdir=home, title="Select file to open")
    with open(filename, "r") as theFile:
        theText = theFile.read()
        text.delete(0.0, END)
        text.insert(END, theText)
    slate.title(filename)
def deleteAll():
    text.delete(0.0, END)
    slate.title("slate")
    del filename
def hello():
    msg.showinfo("About", "slate is a decent plain-text editor. Thanks for using!")
    Label(slate, text="To-Dos: - add \"staying on file\" (instead of having to type the filename over and over again; - copy-paste functions; - and more!").pack()

slate = Tk() #set up window. `slate' is now the name of the window, internally
slate.title("slate") #set up window. `slate' is now the word in the title bar
scrollbar = Scrollbar(slate, orient=VERTICAL) #set up scrollbar
scrollbar.pack( side = RIGHT, fill = Y ) #vertical

text = Text(slate, yscrollcommand=scrollbar.set)
text.pack()
scrollbar.config( command = text.yview )
w = Button(slate, text="Save", command=save)
w2 = Button(slate, text="Open", command=openFile)

w.pack(padx=5, pady=10, side=LEFT)
w2.pack(padx=5, pady=10, side=LEFT)

mainloop()

And this is the error when I run save() (by clicking the save button):

File "slateGUI.py", line 17, in save
    with open(filename, "w") as theFile:
UnboundLocalError: local variable 'filename' referenced before assignment

If I add global filename:

File "slateGUI.py", line 19, in save
    print("Saving to  %s" % filename, end="\r")
NameError: name 'filename' is not defined

Does anyone know how I can fix this? Thanks!

TheTechRobo the Nerd
  • 1,249
  • 15
  • 28

2 Answers2

1

If the exception occurs, keepTheFilename = False. If keepTheFilename = False, the if statement will not be launched, hence filename won't be defined.

def save():
    try: # If the exception occurs, keepTheFilename = False
        yolo = filename
        del yolo
        keepTheFilename = True
    except:
        keepTheFilename = False
    from os.path import expanduser
    home = expanduser("~")
    if keepTheFilename is True: # If the exception occurred, this if statement will not be launched, hence filename haven't been defined
        filename = filedialog.asksaveasfilename(initialdir=home, title="Saving file")
    print("Saving to  %s" % filename, end="\r")
    theText = text.get(0.0, "end-1c") #https://stackoverflow.com/a/14824164/9654083
    with open(filename, "w") as theFile:
        theFile.write(theText)
        print("Saving to  %s, done." % filename)
    slate.title(filename)
Red
  • 26,798
  • 7
  • 36
  • 58
0

So, thanks to @AnnZen's great answer, I figured it out:

def save():
    try: # If the exception occurs, keepTheFilename = False
        yolo = filename
        del yolo
        keepTheFilename = True
    except:
        keepTheFilename = False
    from os.path import expanduser
    home = expanduser("~")
    if keepTheFilename is not True: # If the exception occurred, this if statement will not be launched, hence filename haven't been defined
        filename = filedialog.asksaveasfilename(initialdir=home, title="Saving file")
    else:
        global filename
    print("Saving to  %s" % filename, end="\r")
    theText = text.get(0.0, "end-1c") #https://stackoverflow.com/a/14824164/9654083
    with open(filename, "w") as theFile:
        theFile.write(theText)
        print("Saving to  %s, done." % filename)
    slate.title(filename)

The logic: If keepTheFilename is not defined, it will ask for the path. However, if it is defined, it will save to that original path (using global filename in the else block).

There IS a syntax warning (from global filename):

slateGUI.py:16: SyntaxWarning: name 'filename' is assigned to before global declaration
  global filename

Thanks so much AnnZen!

TheTechRobo the Nerd
  • 1,249
  • 15
  • 28