Python Forum

Full Version: tkinter - global variable not working
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello!

I am using Tkinter and doing GUI so that there is a 'save', 'save as', and 'open' button, along with a text box.
I have got everything working except the 'save' button. I Have tried to set the name from filedialog.askopenfilename(), to a global variable to use in my 'save' function.

I have written my save function so that if the file name already exists, save over that, if not do the save_as function. It works fine when I need to save to an existing file, but when I enter straight into the text box and hit 'save' (NOT save as), it does not run the save_as function, but instead tells me that 'filename' is not defined ?

Is it saying that there is no filename because I didn't open anything ?
Is there a different want to do this that I haven't thought about ?

I cant see what I am doing wrong ? Please help!

def open_file():
    global filename
    filename = filedialog.askopenfilename()
    ask_file= open(filename)
    text.insert(INSERT, ask_file.read())
    return filename

def save_as_file():
    save_file = filedialog.asksaveasfile( mode = "w", defaultextension = '.txt')
    save_f = text.get(0.0, END)
    try:
        save_file.write(save_f.rstrip())
    except:
        showerror(title = "Save Error")

def save_file():
    if os.path.exists(filename):
        save_text = text.get(0.0, END)
        file_save = open(filename, 'w')
        file_save.write(save_text)
        file_save.close()
    else:
        save_as_file()
You never close the file when you read it, so writing to an already open file will be troublesome.
You'd be better off using a class for this:
import tkinter as tk
import tkinter.filedialog as fd
import tkinter.messagebox as tm
import sys


class  FileManager:
    def __init__(self, parent):
        self.parent = parent
        self.filename = None
        self.file_data = None
        self.create_gui()

    def create_gui(self):
        self.mainframe = tk.Frame(self.parent, bd=6, relief=tk.RIDGE)
        self.mainframe.grid(column=0, columnspan=5, row=0, sticky='nsew')
        self.mainframe.grid_rowconfigure(0, weight=1)
        self.mainframe.grid_columnconfigure(0, weight=1)

        self.text = tk.Text(self.mainframe, bd=2, bg='#CEF6EC', width=113, relief=tk.RAISED)
        self.text.grid(row=0, column=0)

        frame2 = tk.Frame(self.parent, bd=2, padx=2, pady=2, relief=tk.RAISED)
        frame2.grid(row=1, rowspan=2, column=0, columnspan=5, sticky='ew')
        frame2.grid_rowconfigure(0, weight=1)
        frame2.grid_columnconfigure(1, weight=1)

        self.open_button = tk.Button(frame2, text='Open', padx=2, pady=2, bd=2, 
                                     relief=tk.RAISED, command=self.open_file)
        self.open_button.grid(row=0, column=0)

        self.save_button = tk.Button(frame2, text='Save', padx=2, pady=2, bd=2, 
                                     relief=tk.RAISED, command=self.save_file)
        self.save_button.grid(row=0, column=1)

        self.quit_button = tk.Button(frame2, text='Quit', padx=2, pady=2, bd=2,
                                     relief=tk.RAISED, command=self.quit)
        self.quit_button.grid(row=0, column=2)



    def get_filename(self):
        self.filename = fd.askopenfilename()
        print(f'filename: {self.filename}')
    
    def open_file(self):
        self.get_filename()
        if self.filename:
            with open(self.filename, 'r') as fp:
                self.file_data = fp.read()
            self.load_text_widget()
        else:
            tm.showerror('read_file', 'File has not been selected')
    
    def load_text_widget(self):
        if self.file_data:
            self.text.insert(tk.INSERT, self.file_data)
        else:
            tm.showerror('load_text_widget', 'No file data')

    def save_file(self, from_text=True):
        if from_text:
            text_data = self.text.get(0.0, tk.END)
            if len(text_data):
                with open(self.filename, 'w') as fp:
                    fp.write(text_data)
            else:
                tm.showerror('save_file', 'No text to save')

    def save_as_file():
        # for you to  finish 
        pass

    def quit(self):
        self.parent.destroy()
        sys.exit(0)

def main():
    root = tk.Tk()
    fm = FileManager(root)
    root.mainloop()


if __name__ == "__main__":
    main()
[attachment=540]