Home > Blockchain >  Clear Grid Label Output from a For Loop in a Function Tkinter
Clear Grid Label Output from a For Loop in a Function Tkinter

Time:06-08

I am trying to clear out my second column of information to which I am printing out in grid format from a for loop within a function using a label. My goal is when I click my Generate button the old output will clear out.

Here is the code:

root = Tk()
root.geometry("700x700")
root.title("NPC Maker")
root.config(bg="light grey")

#Define details label
details_label = Label(root)
npc = {}

#Set NPC Properties list
npc_properties = ["Race",
                "Sex",
                "Name", 
                "Height",
                "Weight",
                "Hair Style",
                "Hair Color",
                "Face",
                "Eye Color",
                "Skin Tone",
                "Voice Tone"]

#Print NPC properties as row headers
for index, row in enumerate(npc_properties):
        properties_label = Label(root, text = row   ":", font=("Aerial 12 bold"))
        properties_label.grid(row=index   1, column=0, sticky=W, pady=18)
        

#Generate funciton
def generate():
        state = True
        while state == True:
                if sex_choice.get() == "Male":
                        if race_choice.get() == "Dwarf":
                                npc = choose_dwarf_male()
                        elif race_choice.get() == "Elf":
                                npc = choose_elf_male()
                        elif race_choice.get() == "Gnome":
                                npc = choose_gnome_male()
                        elif race_choice.get() == "Halfling":
                                npc = choose_halfling_male()
                        elif race_choice.get() == "Human":
                                npc = choose_human_male()
                elif sex_choice.get() == "Female":
                        if race_choice.get() == "Dwarf":
                                npc = choose_dwarf_female()
                        elif race_choice.get() == "Elf":
                                npc = choose_elf_female()
                        elif race_choice.get() == "Gnome":
                                npc = choose_gnome_female()
                        elif race_choice.get() == "Halfling":
                                npc = choose_halfling_female()
                        elif race_choice.get() == "Human":
                                npc = choose_human_female()
                else:
                        pass

                for index,(key, value) in enumerate(npc.items()):
                        details_label = Label(root, text = value, font=("Aerial 12 bold"))
                        details_label.grid(row=index   1, column=1, sticky=W, pady=18)
                state = False
        details_label.destroy()

        return npc
        
    
#Choose Sex of NPC
sex_options = ["Male", "Female"]
sex_choice = StringVar()
sex_choice.set("Choose Sex")
#Choose Race of NPC
race_options = ["Dwarf", "Elf", "Gnome", "Halfling", "Human"]
race_choice = StringVar()
race_choice.set("Choose Race")
#Sex dropdown menu
sex_dropdown_menu = OptionMenu(root, sex_choice, *sex_options).grid(row=0, column=0, pady=15, padx=5)
#Race dropdown menu
race_dropdown_menu = OptionMenu(root, race_choice, *race_options).grid(row=0, column=1, pady=15, padx=5, sticky=W)

#Generate NPC Button
generate_button = Button(root, text="Generate NPC", command=generate).grid(row=0, column=2, pady=15, padx=5, sticky=W)

root.mainloop()

As you can see I tried to do a while loop and just end the state and destroy the grid output but not seeming to work. I cannot access that details_label Label within that function to clear it out.

CodePudding user response:

Since you use same variable details_label in the for loop, so it only references the last created label. Suggest to change details_label to a list to store the instances of labels. You can then using this list to destroy previously created labels before populating new labels.

Also the while loop is not necessary.

Below is modified generate():

details_label = []
npc = {}

#Generate funciton
def generate():
    # need to declare npc as global, otherwise the global one will not be updated
    global npc
    if sex_choice.get() == "Male":
        if race_choice.get() == "Dwarf":
            npc = choose_dwarf_male()
        elif race_choice.get() == "Elf":
            npc = choose_elf_male()
        elif race_choice.get() == "Gnome":
            npc = choose_gnome_male()
        elif race_choice.get() == "Halfling":
            npc = choose_halfling_male()
        elif race_choice.get() == "Human":
            npc = choose_human_male()
    elif sex_choice.get() == "Female":
        if race_choice.get() == "Dwarf":
            npc = choose_dwarf_female()
        elif race_choice.get() == "Elf":
            npc = choose_elf_female()
        elif race_choice.get() == "Gnome":
            npc = choose_gnome_female()
        elif race_choice.get() == "Halfling":
            npc = choose_halfling_female()
        elif race_choice.get() == "Human":
            npc = choose_human_female()
    else:
        npc = {}

    # destroy current labels
    for w in details_label:
        w.destroy()

    # clear the list
    details_label.clear()
    # populate new labels
    for index,(key, value) in enumerate(npc.items()):
        details_label.append(Label(root, text=value, font=("Aerial 12 bold")))
        details_label[-1].grid(row=index 1, column=1, sticky=W, pady=18)

    # since this function is triggered by a button click
    # the return value will be ignored/discarded
    return npc
  • Related