-1

#a program that asks the user to submit a string or number through a graphical user interface (GUI), and that string or number is stored as a new line in an existing text file.it has three buttons: Add Line , Save Changes , and Save and Close .

from tkinter import *
window = Tk()
file = open("user_gui.txt", "a+")
     
def add():
    file.write(user_value.get() + "\n")
    entry.delete(0, END)
     
def save():
    global file
    file.close()
    file = open("user_gui.txt", "a+")
     
def close():
     file.close()
     window.destroy()
     
user_value = StringVar()
entry = Entry(window, textvariable=user_value)
entry.grid(row=0, column=0)
     
button_add = Button(window, text="Add line", command=add)
button_add.grid(row=0, column=1)
     
button_save = Button(window, text="Save changes", command=save)
button_save.grid(row=0, column=2)
     
button_close = Button(window, text="Save and Close", command=close)
button_close.grid(row=0,column=3)
     
window.mainloop()
Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46
  • 1
    Scoping rules. Imagine the function `save` without the `global` statement. Then the variable `file` is local to the function because it is defined in `file = open("user_gui.txt", "a+")`. But you try to use it before the definition with `file.close()`. Better approach: use an object oriented approach and get rid of `global`. – Matthias Sep 21 '20 at 18:37
  • No you can’t simply get rid of `global` because without it the assignment line in that function `file =open(...` without the global statement will make file a local variable in that function. Then because in that function `file` is local the global `file` won’t be closed until the program exits. I.e. the `global` statement where it is makes the code close the file and then reopen it. – DisappointedByUnaccountableMod Sep 21 '20 at 18:40
  • @barny Leaving out global will lead to a sudden halt of the program because you'd get `UnboundLocalError: local variable 'file' referenced before assignment` – Matthias Sep 21 '20 at 18:42
  • Anyway are you trying to just get rid of `global`? – Delrius Euphoria Sep 21 '20 at 18:43
  • [Well it was a thought experiment] No you can’t simply get rid of global because without it the assignment line in that function file =open(... without the global statement will make file a local variable in that function. For more info about variable scope read e.g. https://docs.python.org/3/faq/programming.html?highlight=global#what-are-the-rules-for-local-and-global-variables-in-python and e.g. https://stackoverflow.com/questions/423379/using-global-variables-in-a-function – DisappointedByUnaccountableMod Sep 21 '20 at 18:45
  • As @Matthias stated use a object oriented version of this to get rid of the global. It also have some benefits while you trying to build something like a **context manager**. – Thingamabobs Sep 21 '20 at 18:51
  • 1
    Thanks All and Thanks Cool Cloud , it's useful answer – Sameh Mahmoud Sep 23 '20 at 18:18

1 Answers1

-1

If your Q is, why this wont work without global, then you have to understand that once a file is closed, you cannot write to it. In your code, when the save() is being executed, your closing the file and reopening it. This reopening will just take effect inside the function save(), for this file to be opened and used in other functions, you have to make it available to global scope. Variables defined inside of a function are in local scope. Without making file global, python thinks file used by other functions like add() and close() is the file that you said at the top of your code, which is closed. So writing to a closed file, will give an error. So instead if you just make it global inside the function then the file will be reopened and can be used by other function.

Actually the file is not technically being reopened but instead your overwriting the existing file = ... variable which is closed, with a new file = ... which is will be open. It wont close, unless close() is executed.

If your looking for a way to not use global then you will have to redefine file on top of each function, like:

def add():
    file = open("user_gui.txt", "a+")
    file.write(user_value.get() + "\n")
    file.close()
    entry.delete(0, END)
     
def save():
    file = open("user_gui.txt", "a+")
    file.close()

def close():
    file = open("user_gui.txt", "a+")
    file.close()
    window.destroy()

This way the changes take place immediately, unlike your initial code, where you have to execute the close() function for changes to take place.

Hope this made some sense as its clearly just theory and understanding. Do let me know if something is still unclear.

Cheers

Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46