Search code examples
pythonpython-3.xtkintertkinter-entry

Issue when making new label on button press tkinter


    import tkinter as tk

root = tk.Tk()
root.title("To Do")
root.geometry("500x750")
root.resizable(False, False)

class App:
    def __init__(self, window):
        #Button font
        self.buttonFont = ("Courier", 13, "normal")
        #Header
        self.header = tk.Label(text = "To Do List\n", font = ("Helvetica", 26, "bold"))
        self.header.grid()
        #Add item button
        self.addButton = tk.Button(text = "Add Item", font = self.buttonFont, bg = "green", command = self.OpenAddItem)
        self.addButton.grid(row = 1, column = 0, )
        #Del item button
        self.delButton = tk.Button(text = "Delete Item", font = self.buttonFont, bg = "red")
        self.delButton.grid(row = 1, column = 1, )
        #items frame and stuff
        self.itemsframe = tk.Frame()
        self.itemsframe.grid(row = 2)
        self.item = tk.Label(self.itemsframe, font = ("Helvetica", 11, "normal"))
    def OpenAddItem(self):
        #COnfiguring prompt win
        self.addPromptWin = tk.Toplevel(root)
        self.addPromptWin.title("Prompt")
        self.addPromptWin.geometry("375x100")
        self.addPromptWin.resizable(False,False)
        #Entry label
        self.entryLabel = tk.Label(self.addPromptWin,text = "Enter item name:", font = ("Courier", 11, "normal"))
        self.entryLabel.grid(sticky = tk.E)
        #Adding entry 
        self.entry = tk.Entry(self.addPromptWin, font = ("Courier", 11, "normal"))
        self.entry.grid(row = 0, column = 1)
        self.entry.bind("<Return>", lambda e: self.AddItem())
        #Add new item button
        self.addNewItemButton = tk.Button(self.addPromptWin, text = "Add", font = self.buttonFont, bg = "green", command = self.AddItem)
        self.addNewItemButton.grid(row = 1, sticky = tk.W)
        
    def AddItem(self):
        self.entryValue = self.entry.get()
        
        self.item.config(text = f"1.  {self.entryValue}")
        self.item.pack()
        self.addPromptWin.destroy()

app = App(root) 
root.mainloop()

Hey guys, I'm having an issue with my tkinter gui program. When i call the addItem function, instead of creating a new label every time, it just replaces the current one. Any help would be much appreciated!


Solution

  • You made a Label named self.item and you keep overwriting it, expecting it to magically be a new Label. The fix is simple ~ don't create self.item. Create a list instead and push new Labels onto it as they are needed. This sets the stage for your delete method, as well ~ as you can just unpack everything in the cache, delete the desired item and repack whatever is left in the cache. My example is commented where it counts. I didn't write a delete method for you.

    import tkinter as tk
    
    root = tk.Tk()
    root.title("To Do")
    root.geometry("500x750")
    root.resizable(False, False)
    
    class App:
        def __init__(self, window):
            #Button font
            self.buttonFont = ("Courier", 13, "normal")
            #Header
            self.header = tk.Label(text = "To Do List\n", font = ("Helvetica", 26, "bold"))
            self.header.grid()
            #Add item button
            self.addButton = tk.Button(text = "Add Item", font = self.buttonFont, bg = "green", command = self.OpenAddItem)
            self.addButton.grid(row = 1, column = 0, )
            #Del item button
            self.delButton = tk.Button(text = "Delete Item", font = self.buttonFont, bg = "red")
            self.delButton.grid(row = 1, column = 1, )
            #items frame and stuff
            self.itemsframe = tk.Frame()
            self.itemsframe.grid(row = 2)
            
            ''' you just keep overwriting this '''
            #self.item = tk.Label(self.itemsframe, font = ("Helvetica", 11, "normal"))
            
            #start a cache instead
            self.items = []
            
        def OpenAddItem(self):
            #COnfiguring prompt win
            self.addPromptWin = tk.Toplevel(root)
            self.addPromptWin.title("Prompt")
            self.addPromptWin.geometry("375x100")
            self.addPromptWin.resizable(False,False)
            #Entry label
            self.entryLabel = tk.Label(self.addPromptWin,text = "Enter item name:", font = ("Courier", 11, "normal"))
            self.entryLabel.grid(sticky = tk.E)
            #Adding entry 
            self.entry = tk.Entry(self.addPromptWin, font = ("Courier", 11, "normal"))
            self.entry.grid(row = 0, column = 1)
            self.entry.bind("<Return>", lambda e: self.AddItem())
            #Add new item button
            self.addNewItemButton = tk.Button(self.addPromptWin, text = "Add", font = self.buttonFont, bg = "green", command = self.AddItem)
            self.addNewItemButton.grid(row = 1, sticky = tk.W)
            
        def AddItem(self):
            self.entryValue = self.entry.get()
            
            '''
                you can keep configuring and repacking this for infinity
                it's not going to change the fact that it's the same label every time
            '''
            #self.item.config(text = f"1.  {self.entryValue}")
            #self.item.pack()
            
            #append a new label to the cache instead
            self.items.append(tk.Label(self.itemsframe, font = ("Helvetica", 11, "normal"), anchor='w'))
            
            #config and pack the last item in the cache
            self.items[-1].config(text = f"{len(self.items)}.  {self.entryValue}",)
            self.items[-1].pack(anchor='w')
            
            self.addPromptWin.destroy()
    
    app = App(root) 
    root.mainloop()