jack.py
jack.py

Reputation: 442

Save function not working in Tkinter window

I have a Tkinter program that has Save and Save As functions. I've got Save As working fine, but Save is not.

However, whenever I press the Save button it throws the error: NameError: name 'save_as_dialog' is not defined

def save_as():
    notepad_save = notepad.get('1.0', END).strip('\n') 

    head_save = str(head_entry.get().strip('\n')) + '\n' 
    body_save = str(body_entry.get().strip('\n')) + '\n'
    tail_save = str(tail_entry.get().strip('\n')) + '\n'
    legs_save = str(legs_entry.get().strip('\n')) + '\n'


    save_as_dialog = tkfd.asksaveasfilename(initialfile = file_name, 
    initialdir = '/Users/Documents', title = "Save as", defaultextension = 
    '.txt', filetypes = [('Text files', '*.txt')])

with open(save_as_dialog, 'w') as output_file:
   output_file.write(head_save)
   output_file.write(body_save)
   output_file.write(tail_save)
   output_file.write(legs_save)

   output_file.write(notepad_save)

def save():

    notepad_save = notepad.get('1.0', END).strip('\n') 

    head_save = str(head_entry.get().strip('\n')) + '\n' 
    body_save = str(body_entry.get().strip('\n')) + '\n'
    tail_save = str(tail_entry.get().strip('\n')) + '\n'
    legs_save = str(legs_entry.get().strip('\n')) + '\n'

    try:
        with open(save_as_dialog, 'w') as output_file:
            output_file.write(head_save)
            output_file.write(body_save)
            output_file.write(tail_save)
            output_file.write(legs_save)

            output_file.write(notepad_save)

    except NameErrors:
        save_as()

As you can see, the file stores different information on different lines. This is a crucial part of the program, so I need to keep that part intact. The thing is, when I press the save button it throws the error: NameError: name 'save_as_dialog' is not defined. I've tried having the 'except' by itself and with AttributeError instead, but it still spits the same error. I'm stuck!

Edit: My new code, still not working:

global save_as_dialog
global opened_file_filename
global filepath

filepath = r"C:\Users\Documents"
opened_file_filename = None

def _open():
    opened_file_filename = tkfd.askopenfilename(title = "Open...", 
    defaultextension = '.txt', filetypes = [('Text files', '*.txt')])

def save_as():
    notepad_save = notepad.get('1.0', END).strip('\n') #

    head_save = head_entry.get().strip('\n') + '\n'  
    body_save = body_entry.get().strip('\n') + '\n'
    tail_save = tail_entry.get().strip('\n') + '\n'
    legs_save = legs_entry.get().strip('\n') + '\n'


    save_as_dialog = tkfd.asksaveasfilename(initialfile = file_name, initialdir 
    = filepath, title = "Save as", defaultextension = '.txt', filetypes = 
    [('Text files', '*.txt')])


    with open(opened_file_filename, 'w') as output_file:
        output_file.write(head_save)
        output_file.write(body_save)
        output_file.write(tail_save)
        output_file.write(legs_save)

        output_file.write(notepad_save)

    opened_file_filename = save_as_dialog

    time_saved_label.config(text = "Saved" )
    print(opened_file_filename)

def save():
    notepad_save = notepad.get('1.0', END).strip('\n') 

    head_save = head_entry.get().strip('\n') + '\n' 
    body_save = body_entry.get().strip('\n') + '\n'
    tail_save = tail_entry.get().strip('\n') + '\n'
    legs_save = legs_entry.get().strip('\n') + '\n'

    if opened_file_filename is None:
        save_as()

    else:
        with open(opened_file_filename, 'w') as output_file:
            output_file.write(head_save)
            output_file.write(body_save)
            output_file.write(tail_save)
            output_file.write(legs_save)

            output_file.write(notepad_save)

    time_saved_label.config(text = "Saved" )
    print(opened_file_filename)

Throws the error: with open(opened_file_filename, 'w') as output_file: FileNotFoundError: [Errno 2] No such file or directory: ''

Upvotes: 0

Views: 341

Answers (1)

Jakub Šolín
Jakub Šolín

Reputation: 146

That's because you are creating the save_as_dialog variable inside of save_as(). The variable isn't defined in save(). Declaring the variable outside of those functions' scope should be the simplest way.

I'd do something like save_as_dialog = None in a scope containing the two functions and then add

if save_as_dialog is None:
    return save_as()

at the start of the save() function.

The result should look kind of like this:

from tkinter import filedialog

#  Filename of our file.
opened_file_filename = None


def save_as():
    """
    Opens a file dialog and saves stuff to it.
    :return: None
    """
    global opened_file_filename  # we wanna use the opened_file_filename from global scope

    opened_file_filename = filedialog.askopenfilename()

    with(open(opened_file_filename), 'w') as file:
        # write stuff to file here
        pass


def save():
    """
    If we have a filename, save stuff to it. Otherwise do save_as().
    :return: None
    """
    global opened_file_filename  # we wanna use the opened_file_filename from global scope

    if opened_file_filename is None:
        # it is none, which means we have not chosen a filename yet
        return save_as()

    with(open(opened_file_filename), 'w') as file:
        # write stuff to file here
        pass

# rest of your code

Upvotes: 2

Related Questions