pythontkintertkinter-entrynameerror

Tkinter entry box is not defined when it appears for multiple windows


I am trying to write code, where depending on the user input of the first window, another one pops up. However, the variable "r" appears on multiple secondary windows

So the user selects the configuration they want and the corresponding window to input their value pops up. If the user chooses "groove" I get a: NameError: name 'r_entry' is not defined for line 20, if the user chooses "groove" the same error for line 9.

Why is this happening? And how can this be solved?

import tkinter
from tkinter import *
from tkinter import ttk
from tkinter import messagebox

def gradation_enter_data():
    global r
    r=r_entry.get()

    if r:    
        gradationmenu.destroy()

    else:
        tkinter.messagebox.showwarning(title="Error", message="Provide values for all entry boxes!")
        return

def groove_enter_data():
    global r
    r=r_entry.get()

    if r:
        groovemenu.destroy()

    else:
        tkinter.messagebox.showwarning(title="Error", message="Provide values for all entry boxes!")
        return

def configuration_match_function():

    match configuration:
        case "groove":
            #GUI 
            groovemenu = tkinter.Tk()
            groovemenu.title("Groove Dimensions Data Entry")

            frame = tkinter.Frame(groovemenu)
            frame.pack()

            #DIMENSIONS
            dimensions_frame =tkinter.LabelFrame(frame, text="Dimensions")
            dimensions_frame.grid(row= 0, column=0, padx=20, pady=10)

            r_label = tkinter.Label(dimensions_frame, text="r:")
            r_label.grid(row=0, column=0)

            r_entry = tkinter.Entry(dimensions_frame)
            r_entry.grid(row=1, column=0)

            for widget in dimensions_frame.winfo_children():
                widget.grid_configure(padx=10, pady=5)

            # ENTER DATA BUTTON
            button = tkinter.Button(frame, text="Enter Data", command=groove_enter_data)
            button.grid(row=3, column=0, sticky="news", padx=20, pady=10)

            groovemenu.mainloop()

        case "gradation":
            #Gradation
            #GUI 
            gradationmenu = tkinter.Tk()
            gradationmenu.title("Gradation Dimensions Data Entry")

            frame = tkinter.Frame(gradationmenu)
            frame.pack()

            #DIMENSIONS
            dimensions_frame =tkinter.LabelFrame(frame, text="Dimensions")
            dimensions_frame.grid(row= 0, column=0, padx=20, pady=10)

            r_label = tkinter.Label(dimensions_frame, text="r:")
            r_label.grid(row=0, column=0)

            r_entry = tkinter.Entry(dimensions_frame)
            r_entry.grid(row=1, column=0)

            for widget in dimensions_frame.winfo_children():
                widget.grid_configure(padx=10, pady=5)

            # ENTER DATA BUTTON
            button = tkinter.Button(frame, text="Enter Data", command=gradation_enter_data)
            button.grid(row=3, column=0, sticky="news", padx=20, pady=10)

            gradationmenu.mainloop()

def enter_data():
    global configuration
    try:
        if(y.get()==0):
            configuration="groove"
        elif(y.get()==1):
            configuration="gradation"
        else:
            raise Exception("Something went wrong")
    except Exception as ex:
        tkinter.messagebox.showwarning(title="Error!", message=ex)
        return

    window.destroy()
    configuration_match_function()

#GUI 

window = tkinter.Tk()
window.title("Stress Data Entry")

frame = tkinter.Frame(window)
frame.pack()

#SHAFT CONFIGURATION

configuration_frame =tkinter.LabelFrame(frame, text="Shaft Configuration")
configuration_frame.grid(row= 1, column=1, padx=20, pady=10)

configuration_option=["Groove", "Gradation"]

y=IntVar()

for index in range(len(configuration_option)):
    radiobutton= Radiobutton(configuration_frame, 
    text=configuration_option[index], 
    variable=y, 
    value=index,
    padx=20,
    pady=10,
    )

for widget in configuration_frame.winfo_children():
    widget.grid_configure(padx=10, pady=5)

# ENTER DATA BUTTON
button = tkinter.Button(frame, text="Enter Data", command=enter_data)
button.grid(row=3, column=1, sticky="news", padx=20, pady=10)

window.mainloop()

Solution

  • All I needed to do was add global r_entry at the configuration_match_function(). This is because the variable r_entry is assigned to global r in a whole different function (i.e. groove_enter_data()), so it remained non defined between those 2 functions. The code would look something like:

    ....
    def configuration_match_function():
        global r_entry
    
        match configuration:
            case "groove":
    ....