Home > Software design >  Remove a widget generated with for loop
Remove a widget generated with for loop

Time:11-22

I work on a python project, and I would like to create a history where each history is erasable with a "delete" button placed in the Frame of the widget

I tried to add the « delete » button in the loop where the widget was generated but it didn’t work as planned

history_files = os.listdir(history_directory)
history_files.sort(reverse=True)
number_of_h = 0
for file in history_files:
    file_dat = open(history_directory "\\" file)
    file_dat_lines = file_dat.readlines()
    action_amount_h = file_dat_lines[0]
    h_comment = file_dat_lines[1]
    h_date = file_dat_lines[2]
    h_time = file_dat_lines[3]
    history_f = Frame(history_win_f, bg=bg_theme, height=120, width=485, highlightbackground=bg_theme_2, highlightthickness=1)
    history_f.grid_propagate(False)
    history_f.columnconfigure(1, weight=70)
    history_f.columnconfigure(2, weight=30)
    history_f.rowconfigure(1, weight=60)
    history_f.rowconfigure(2, weight=40)
    action_h_f = LabelFrame(history_f, bg=bg_theme, width=390, height=120, font='Courrier 13 bold', labelanchor="n")
    action_h_f.grid_propagate(False)
    action_h_f.rowconfigure(1, weight=30)
    action_h_f.rowconfigure(2, weight=70)
    action_h_f.columnconfigure(1, weight=100)
    action_h_f.grid(row=1, column=1, sticky="w")
    date_h_f = LabelFrame(history_f, bg=bg_theme, height=120, width=95, text=' Date ', labelanchor="n", font='Courrier 10 bold')
    date_h_f.grid(row=1, rowspan=2, column=2, sticky="nesw")
    date_h_f.rowconfigure(1, weight=50)
    date_h_f.rowconfigure(2, weight=50)
    date_h_f.columnconfigure(1, weight=100)
    date_l = Label(date_h_f, text="Le " h_date, bg=bg_theme, fg=fg_theme_2, font='Courrier 8').grid(row=1, column=1, sticky="nesw")
    time_l = Label(date_h_f, text="A " h_time, bg=bg_theme, fg=fg_theme_2, font='Courrier 8').grid(row=2, column=1, sticky="nesw")
    date_h_f.grid_propagate(False)
    h_edit_a = Label(action_h_f, bg=bg_theme, font="Courrier 11", justify="center")
    h_edit_a_str = ""

I would appreciate any explanation, and if the code is simple, because I'm still a newbie. Thanks !

CodePudding user response:

It's hard to know what do you wish to accomplish. I can't see any button on your code and I'm not clear what do you wish to delete when the delete button is clicked.

As per my understanding, If the delete button is on the history_f, and you wish to remove or delete the Labels i.e. date_l and time_l then following is how you can do it.

for file in history_files:
    file_dat = open(history_directory "\\" file)
    file_dat_lines = file_dat.readlines()
    action_amount_h = file_dat_lines[0]
    h_comment = file_dat_lines[1]
    h_date = file_dat_lines[2]
    h_time = file_dat_lines[3]
    history_f = Frame(history_win_f, bg=bg_theme, height=120, width=485, highlightbackground=bg_theme_2, highlightthickness=1)
    history_f.grid_propagate(False)
    history_f.columnconfigure(1, weight=70)
    history_f.columnconfigure(2, weight=30)
    history_f.rowconfigure(1, weight=60)
    history_f.rowconfigure(2, weight=40)
    action_h_f = LabelFrame(history_f, bg=bg_theme, width=390, height=120, font='Courrier 13 bold', labelanchor="n")
    action_h_f.grid_propagate(False)
    action_h_f.rowconfigure(1, weight=30)
    action_h_f.rowconfigure(2, weight=70)
    action_h_f.columnconfigure(1, weight=100)
    action_h_f.grid(row=1, column=1, sticky="w")
    date_h_f = LabelFrame(history_f, bg=bg_theme, height=120, width=95, text=' Date ', labelanchor="n", font='Courrier 10 bold')
    date_h_f.grid(row=1, rowspan=2, column=2, sticky="nesw")
    date_h_f.rowconfigure(1, weight=50)
    date_h_f.rowconfigure(2, weight=50)
    date_h_f.columnconfigure(1, weight=100)
    date_l = Label(date_h_f, text="Le " h_date, bg=bg_theme, fg=fg_theme_2, font='Courrier 8').grid(row=1, column=1, sticky="nesw")
    time_l = Label(date_h_f, text="A " h_time, bg=bg_theme, fg=fg_theme_2, font='Courrier 8').grid(row=2, column=1, sticky="nesw")
    date_h_f.grid_propagate(False)
    h_edit_a = Label(action_h_f, bg=bg_theme, font="Courrier 11", justify="center")
    h_edit_a_str = ""

    ############################################
    #assume button is on action_h_f
    ttk.Button(action_h_f, text="delete", command=lambda : 
                           delete_record(date_l, time_l)

def delete_record(widget1, widget2):
    widget1.destroy()
    widget2.destroy()

you must pass the reference of both the label to the delete_record() function.

Just my guess, correct me if I am wrong.

CodePudding user response:

Create the delete button inside history_f frame as well and destroy history_f when it is clicked. Note that you do not call any layout function on history_f, so it will not be shown and you will get a blank window.

Below are the required changes:

...
for file in history_files:
    ...
    history_f = Frame(history_win_f, bg=bg_theme, height=120, width=485, highlightbackground=bg_theme_2, highlightthickness=1)
    history_f.pack() # call layout function on history_f
    ...
    h_edit_a_str = ""

    # create delete button and destroy history_f when clicked
    Button(history_f, text="Delete", command=history_f.destroy).grid(row=1, column=4)
  • Related