How to get input from a tkinter entry box, to a variable in another function?

Question:

I am writing a files manager in python. One of the functions is to rename a file. Instead of entering the filename in the terminal with the ‘input()’ function, I want an input box to pop up so the user can enter the filename in there.

This is the function that renames the file.

import os
import tkinter
from tkinter import filedialog
from tkinter import messagebox

def rename_file():
    messagebox.showinfo(title="Rename File", message="Select the file you want to rename!")
    renameFileSource = filedialog.askopenfilename()
    if renameFileSource == "":
        messagebox.showinfo(title="File Select Canceled", message="You have canceled the file selection!")
    else:
        try:
            namePath = os.path.dirname(renameFileSource)
            renameFileDestination = os.path.splitext(namePath)[1]
            messagebox.showinfo(title="Rename File", message="Enter the new file name!")
            entry_box()
            if renameFileInput == "":
                messagebox.showinfo(title="No input", message="You have not entered anything!")
            else:
                newPath = os.path.join(namePath, renameFileInput + renameFileDestination)
                os.rename(renameFileSource, newPath)
                messagebox.showinfo(title="File Renamed", message="The file has succesfully been renamed!")
        except OSError as renameFileError:
            messagebox.showerror(title="File Error", message="The following error has occured:nn"+ str(renameFileError) + "nnPlease try again!")

This is the function that has the input box I made with tkinter. I want this function to pass the input to the variable ‘renameFileInput’ in the ‘rename_file()’ function

def entry_box():
    entryBox = tkinter.Tk()

    def rename_input():
        renameFileInput = entryInput.get()
        entryBox.destroy()

    tkinter.Label(entryBox, text="Enter data here: ").pack()
    entryInput = tkinter.Entry(entryBox)
    entryInput.pack()
    button = tkinter.Button(entryBox, text="GO!", width=3, height=1, command=rename_input)
    button.pack()
    entryBox.mainloop()

This is the function that has my main GUI.

def gui_window():
    guiWindow = tkinter.Tk()
    tkinter.Label(guiWindow, text="Lucas' Files Managern", fg="green", font=("", 40, "normal", "underline")).pack()
    tkinter.Button(guiWindow, text="Rename File", width=25, height=1, bg="blue", fg="red", font=("", "20", "bold"), command=rename_file).pack()
    tkinter.Button(guiWindow, text="Exit Program", width=25, height=1, bg="blue", fg="red", font=("", "20", "bold"), command=guiWindow.destroy).pack()
    guiWindow.mainloop()

gui_window()

When I run the code as shown above, I get the following error: NameError: name ‘renameFileInput’ is not defined.

I have uploaded the code to my entire files manager to github: https://github.com/GierLucas/File-Manager

Asked By: GierLucas

||

Answers:

What is happening is that your program is trying to acces the variable renameFileInput before it creates it, so a NameError exception is raised. From the code you linked (here), you define that variable in the function rename_input (which is inside of entry_box) and try to use it in the function rename_file.

The problem is that the variable created in rename_input is destroyed when the function ends, that is when its scope ends. To get the rest of the code know that value you have a few options. The recommended is to return that value, so you can transfer it to the scope where that function was called. The other option is to make that variable a global variable. This means that variable can be accessed in every part of your code.

To globalize a variable in a scope, type global <variable> at the start of the function, in your case:


def entry_box():
    entryBox = tkinter.Tk()
    def callback():
        global renameFileInput
        renameFileInput = entryInput.get()
        print(renameFileInput)
        entryBox.destroy()
    tkinter.Label(entryBox, text="Enter data here: ").pack()
    entryInput = tkinter.Entry(entryBox)
    entryInput.pack()
    btn = tkinter.Button(entryBox, text="GO!", width=3, height=1, command=callback)
    btn.pack()
    entryBox.mainloop()

This should solve the problem you state, although your code has more errors, starting from that mainloop you have in that method. It will not let you keep the application as you would expect.

Further information

To create popup windows better use TopLevel class. See here a related question.

About scopes

About return in functions, see here

Answered By: Luis G.
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.