Home > Software design >  how to delete a specific item in the list after a button is clicked in tkinter python
how to delete a specific item in the list after a button is clicked in tkinter python

Time:10-19

Below is a small code where if you click add button a pop-up will appear where you write desired number. The number in the bottom represents the sum of all numbers you entered. What I am trying to achieve is to update the sum_lbl and index_no as I delete any of the labels.

Code:

from tkinter import *

root = Tk()
root.geometry('400x400')
add_room_area_var= StringVar(None)

area_lst = []
index_no = 0

def destroy(widget):
    widget.destroy()

def add_():
    add_room_area = Toplevel(root)
    add_room_area.title('Add Room area')
    add_room_area.wm_minsize(200, 50)
    add_room_area.resizable(False, False)
    add_room_area.transient(root)

    add_r_area_frame = LabelFrame(add_room_area, text='  Room area  ', labelanchor=N)
    add_r_area_frame.config(padx=3, pady=3)
    add_r_area_frame.pack(fill=X, padx=10, pady=10)

    add_r_area_entry = Entry(add_r_area_frame, textvariable=add_room_area_var)
    add_r_area_entry.pack(fill=X)
    add_r_area_entry.focus_set()

    while True:
        def ok_():
            global index_no
            name = add_room_area_var.get()
            index_no  = 1

            entry_frame = Frame(root)
            index_lbl = Label(entry_frame, text=index_no)
            add_room_lbl = Label(entry_frame, text=name, width=12, bg='gray30', fg='white', pady=5)
            close_button = Button(entry_frame, text='X', command=lambda:destroy(entry_frame))

            entry_frame.pack(anchor=N, padx=1)
            index_lbl.pack(side=LEFT, padx=3)
            add_room_lbl.pack(fill=X, side=LEFT)
            close_button.pack(side=RIGHT)

            area_lst.append(int(name))
            add_room_area.destroy()

            area_sum = sum(area_lst)
            sum_lbl.config(text=area_sum)

        break

    ok_button = Button(add_room_area, text='Ok', command=ok_)
    ok_button.pack()

btn = Button(root, text='Add', command=add_)
btn.pack()

sum_lbl = Label(root, font=25)
sum_lbl.pack(side=BOTTOM, pady=15)

root.mainloop()

Output: Output

After deleting the 3rd and 4th label the output is: Output after deletion

CodePudding user response:

I would suggest to change area_lst to dictionary using the frame as the key and the two labels as the value for each row.

Then update destroy() to use area_lst to update the total and indexes:

from tkinter import *

root = Tk()
root.geometry('400x400')
add_room_area_var= StringVar(None)

area_lst = {}  # dictionary to hold labels of each row using frame as the key

def destroy(frame):
    frame.destroy()
    del area_lst[frame]
    update_total()
    # update index of remaining rows
    for idx, (lbl, _) in enumerate(area_lst.values(), 1):
        lbl['text'] = idx

# function to update the total label
def update_total():
    area_sum = sum(int(room['text']) for _, room in area_lst.values())
    sum_lbl.config(text=area_sum)

def add_():
    add_room_area = Toplevel(root)
    add_room_area.title('Add Room area')
    add_room_area.wm_minsize(200, 50)
    add_room_area.resizable(False, False)
    add_room_area.transient(root)

    add_r_area_frame = LabelFrame(add_room_area, text='  Room area  ', labelanchor=N)
    add_r_area_frame.config(padx=3, pady=3)
    add_r_area_frame.pack(fill=X, padx=10, pady=10)

    add_r_area_entry = Entry(add_r_area_frame, textvariable=add_room_area_var)
    add_r_area_entry.pack(fill=X)
    add_r_area_entry.focus_set()

    def ok_():
        name = add_room_area_var.get()

        entry_frame = Frame(root)
        index_lbl = Label(entry_frame, text=len(area_lst) 1)
        add_room_lbl = Label(entry_frame, text=name, width=12, bg='gray30', fg='white', pady=5)
        close_button = Button(entry_frame, text='X', command=lambda:destroy(entry_frame))

        entry_frame.pack(anchor=N, padx=1)
        index_lbl.pack(side=LEFT, padx=3)
        add_room_lbl.pack(fill=X, side=LEFT)
        close_button.pack(side=RIGHT)

        # store current row to area_lst
        area_lst[entry_frame] = (index_lbl, add_room_lbl)
        add_room_area.destroy()

        update_total()

    ok_button = Button(add_room_area, text='Ok', command=ok_)
    ok_button.pack()

btn = Button(root, text='Add', command=add_)
btn.pack()

sum_lbl = Label(root, font=25)
sum_lbl.pack(side=BOTTOM, pady=15)

root.mainloop()

CodePudding user response:

You can allow buttons to call multiple commands, so for your 'close_button' button, I added two more commands: remove the name from 'area_lst' and update the 'sum_lbl' text with the new sum for 'area_lst'

Like this:

from tkinter import *

root = Tk()
root.geometry('400x400')
add_room_area_var= StringVar(None)

area_lst = []
index_no = 0

def destroy(widget):
    widget.destroy()

def add_():
    add_room_area = Toplevel(root)
    add_room_area.title('Add Room area')
    add_room_area.wm_minsize(200, 50)
    add_room_area.resizable(False, False)
    add_room_area.transient(root)

    add_r_area_frame = LabelFrame(add_room_area, text='  Room area  ', labelanchor=N)
    add_r_area_frame.config(padx=3, pady=3)
    add_r_area_frame.pack(fill=X, padx=10, pady=10)

    add_r_area_entry = Entry(add_r_area_frame, textvariable=add_room_area_var)
    add_r_area_entry.pack(fill=X)
    add_r_area_entry.focus_set()

    while True:
        def ok_():
            global index_no
            name = add_room_area_var.get()
            index_no  = 1

            entry_frame = Frame(root)
            index_lbl = Label(entry_frame, text=index_no)
            add_room_lbl = Label(entry_frame, text=name, width=12, bg='gray30', fg='white', pady=5)
            close_button = Button(entry_frame, text='X', command=lambda:[destroy(entry_frame), area_lst.remove(int(name)), sum_lbl.config(text=sum(area_lst))])

            entry_frame.pack(anchor=N, padx=1)
            index_lbl.pack(side=LEFT, padx=3)
            add_room_lbl.pack(fill=X, side=LEFT)
            close_button.pack(side=RIGHT)

            area_lst.append(int(name))
            add_room_area.destroy()

            area_sum = sum(area_lst)
            sum_lbl.config(text=area_sum)

        break

    ok_button = Button(add_room_area, text='Ok', command=ok_)
    ok_button.pack()

btn = Button(root, text='Add', command=add_)
btn.pack()

sum_lbl = Label(root, font=25)
sum_lbl.pack(side=BOTTOM, pady=15)

root.mainloop()
  • Related