Search code examples
python-3.xtkintertabslabeldestroy

python, tkinter, how to destroy labels in two different tabs with for loop?


Thanks to @Miraj50 that helped me with the .destroy() tkinter: how to write a for loop to destroy a list of labels? For the next stage, I am trying to destroy the labels in both tabs. I knew how to share the same list to different tabs, but I don't know how to "link" them to the tabs. With my limited knowledge I tried

def remove(self, name):
    for name in tabs[name]:
        for employee in labelemployee:
            labelemployee[employee].destroy()

and it gives me this error:

TypeError: remove() missing 1 required positional argument: 'name'  

then I tried

"for name in tabs["Requests"]" 

just to see if it works or not. It still has the same error. If someone can assist me with this hump and clear my confusion, please. Here is the complete code:

import tkinter as tk
from tkinter import ttk

labelemployee={}
upper_tabs = ["Final", "Requests", "Control"]
tabs = {}

class Application(ttk.Frame): #inherent from frame.

    def __init__(self, parent):
        tk.Frame.__init__(self, parent, bg="LightBlue4")
        self.parent = parent
        self.Employees = ["A", "B", "C", "D"]
        self.pack(fill=tk.BOTH, expand=1)
        self.GUI()

    def GUI(self): #the function that runs all the GUI functions.
        self.create_tabs()
        self.buttons("Control")
        for name in upper_tabs[:2]:
        self.create_grid(name)
        self.add_left_names("Requests")
        self.add_left_names("Final")

    def create_tabs(self):
        self.tabControl = ttk.Notebook(self, width=1000, height=400)
        for name in upper_tabs:
            self.tab=tk.Frame(self.tabControl, bg='thistle')
            self.tabControl.add(self.tab, text=name)
            tabs[name] = self.tab
            self.tabControl.grid(row=0, column=0, sticky='nsew')   

    def create_grid(self, name):
        for i in range (7):
            for j in range(7):
                self.label = tk.Label(tabs[name], relief="ridge", 
                     width=12, height=3)
                self.label.grid(row=i, column=j, sticky='nsew')

    def buttons(self, name):
        self.button=tk.Button(tabs[name], text="Clear", bg="salmon",   
            command = self.remove)
        self.button.pack()

    def add_left_names(self, name):
       #--------add in name labels on the side--------------        
        i=2
        for employee in self.Employees:
            self.label=tk.Label(tabs[name], text=employee ,  fg="red", 
               bg="snow")
            self.label.grid(row=i,column=0)
            labelemployee[employee]=self.label
            i +=1

    **def remove(self, name):
        for name in tabs[name]:
            for employee in labelemployee:
            labelemployee[employee].destroy()**

def main():
    root = tk.Tk()
    root.title("class basic window")
    root.geometry("1000x500")
    root.config(background="LightBlue4")
    app = Application(root)
    root.mainloop()

if __name__ == '__main__':
    main()

Solution

  • First of all you need to keep track of all the labels. Here just assigning the labels in add_left_names will override the previous label. So I stored the labels in a list which is the value to the employee key. Now in the remove function, you just need to iterate on all these labels in labelemployee and destroy them.

    import tkinter as tk
    from tkinter import ttk
    from collections import defaultdict
    
    labelemployee=defaultdict(list)
    upper_tabs = ["Final", "Requests", "Control"]
    tabs = {}
    
    class Application(ttk.Frame): #inherent from frame.
    
        def __init__(self, parent):
            tk.Frame.__init__(self, parent, bg="LightBlue4")
            self.parent = parent
            self.Employees = ["A", "B", "C", "D"]
            self.pack(fill=tk.BOTH, expand=1)
            self.GUI()
    
        def GUI(self): #the function that runs all the GUI functions.
            self.create_tabs()
            self.buttons("Control")
            for name in upper_tabs[:2]:
                self.create_grid(name)
            self.add_left_names("Requests")
            self.add_left_names("Final")
    
        def create_tabs(self):
            self.tabControl = ttk.Notebook(self, width=1000, height=400)
            for name in upper_tabs:
                self.tab=tk.Frame(self.tabControl, bg='thistle')
                self.tabControl.add(self.tab, text=name)
                tabs[name] = self.tab
                self.tabControl.grid(row=0, column=0, sticky='nsew')   
    
        def create_grid(self, name):
            for i in range (7):
                for j in range(7):
                    self.label = tk.Label(tabs[name], relief="ridge", width=12, height=3)
                    self.label.grid(row=i, column=j, sticky='nsew')
    
        def buttons(self, name):
            self.button=tk.Button(tabs[name], text="Clear", bg="salmon", command=self.remove)
            self.button.pack()
    
        def add_left_names(self, name):
           #--------add in name labels on the side--------------        
            i=2
            for employee in self.Employees:
                self.label=tk.Label(tabs[name], text=employee, fg="red", bg="snow")
                self.label.grid(row=i,column=0)
                labelemployee[employee].append(self.label)
                i +=1
    
        def remove(self):
            for employee in labelemployee:
                for label in labelemployee[employee]:
                    label.destroy()
    
    def main():
        root = tk.Tk()
        root.title("class basic window")
        root.geometry("1000x500")
        root.config(background="LightBlue4")
        app = Application(root)
        root.mainloop()
    
    if __name__ == '__main__':
        main()