Home > Blockchain >  tkinter destroy function does not release the removed widget space?
tkinter destroy function does not release the removed widget space?

Time:03-10

I tried to use tkinter to design a simple function:

Add a row for text entry when user clicks "ADD ROW" button

Delete the last row when user clicks "DELETE ROW" button for redundant rows.

However, when I add a new row after I delete some rows, those space that occupied by the deleted rows will be skipped instead of overlapped.

Here is what I realized my function

import tkinter as tk

#------------------------------------
def addrow():
    frame = tk.Frame(root)
    frame.pack()

    lab1 = tk.Label(frame, text='keyword')
    lab1.grid(row=0, column=0)

    ent1 = tk.Entry(frame,justify='center')
    ent1.grid(row=1, column=0)

    lab2 = tk.Label(frame, text='value')
    lab2.grid(row=0, column=1)

    ent2 = tk.Entry(frame,justify='center')
    ent2.grid(row=1, column=1)

    all_labels.append( (lab1, lab2) )
    all_entries.append( (ent1, ent2) )
#------------------------------------
def delrow():
    print("Delete")

    frame = tk.Frame(root)
    frame.pack()
    
    all_labels[-1][0].destroy()
    all_labels[-1][1].destroy()
    all_labels.pop(-1)


    all_entries[-1][0].destroy()
    all_entries[-1][1].destroy()
    all_entries.pop(-1)
#------------------------------------
def saveandclose():
    df_dict = {}
    for number, (ent1, ent2) in enumerate(all_entries):
        print(number, ent1.get(), ent2.get())

    for (ent1, ent2) in all_entries:
        df_dict[ent1.get()] = ent2.get()
    root.destroy()
    return df_dict
#------------------------------------
all_labels = []
all_entries = []

root = tk.Tk()
root.geometry('500x300')

showButton = tk.Button(root, text='Save and close', command=saveandclose)
showButton.pack()

addboxButton = tk.Button(root, text='ADD ROW', fg="Red", command=addrow)
delboxButton = tk.Button(root, text='DELETE ROW', fg="Red", command=delrow)
addboxButton.pack()
delboxButton.pack()
root.mainloop()

#------------------------------------

Issue Demonstration

Appreciate any feedback, thank you

CodePudding user response:

It is because the frame which holds those labels and entries is not destroyed and still occupies the space.

You need to store those frames as well and destroy the last frame instead:

def addrow():
    frame = tk.Frame(root)
    frame.pack()

    lab1 = tk.Label(frame, text='keyword')
    lab1.grid(row=0, column=0)

    ent1 = tk.Entry(frame,justify='center')
    ent1.grid(row=1, column=0)

    lab2 = tk.Label(frame, text='value')
    lab2.grid(row=0, column=1)

    ent2 = tk.Entry(frame,justify='center')
    ent2.grid(row=1, column=1)

    all_frames.append(frame)
    #all_labels.append( (lab1, lab2) )
    all_entries.append( (ent1, ent2) )
#------------------------------------
def delrow():
    print("Delete")

    # remove frame from list and destroy it
    all_frames.pop().destroy()

    #all_labels.pop()
    all_entries.pop()
#------------------------------------
...
all_frames = []
#all_labels = []  # it is not necessary at all
all_entries = []
...
  • Related