Below is the code for a smaller version of a project I am working on. Basically when I try to delete one of the entries, the delete function works, but only once. After that it starts duplicating the entries I have deleted until giving me the IndexError: list assignment index out of range
from tkinter import *
gui = Tk()
details_list = []
counters = {'total_entires':0, 'entries_count':0}
error_print = Label(gui)
name_entry = Entry(gui)
name_entry.grid(column=1, row=0, sticky=W)
delete_row_entry = Entry(gui, width=5)
delete_row_entry.grid(column=4,row=3, sticky=W, pady=(2,0))
def print_entries():
global details_list, row_display, name_display
line_no = ""
for x in range(len(details_list)):
line_no = str(x 1)
row_display = Label(gui, text=line_no)
row_display.grid(column=0, row=x 2)
name_display = Label(gui, text=(details_list[x][0]))
name_display.grid(column=1, row=x 2)
def delete_row():
global details_list, row_display
del details_list[int(delete_row_entry.get()) - 1]
entries_count = counters['entries_count']
counters['total_entires'] -= 1
delete_row_entry.delete(0,'end')
row_display.destroy()
name_display.destroy()
print_entries()
def append_name():
details_list.append([name_entry.get()])
counters['total_entires'] = 1
def labels():
Label(gui, text='Row').grid(column=0, row=1, sticky=W, padx=(0,5))
Label(gui, text='Name').grid(column=1, row=1, sticky=W, padx=5)
def buttons():
Button(gui, text='Quit', command=quit, width=15).grid(column=4, row=0, sticky=W)
Button(gui, text='Append Details', command=append_name, width=15).grid(column=4, row=1,
sticky=W)
Button(gui, text='Print Details', command=print_entries, width=15).grid(column=4, row=2,
sticky=W)
Button(gui, text='Delete Row', command=delete_row, width=10).grid(column=4, row=3,
sticky=E)
def main():
labels()
buttons()
gui.mainloop()
main()
CodePudding user response:
There are two issues in your code:
- you have created new set of labels whenever
print_entries()
is executed - the two
.destroy()
lines just destroy the labels in the last row of the set of labels created insideprint_entries()
To fix the issues:
- create a list to store those labels created inside
print_entries()
- delete existing labels before populating new labels inside
print_entries()
Below are the modified print_entries()
and delete_row()
functions:
...
# create a list to store those labels
label_list = []
def print_entries():
# clear current table
for w in label_list:
w.destroy()
label_list.clear()
# show the new table
for x in range(len(details_list)):
row_display = Label(gui, text=x 1)
row_display.grid(column=0, row=x 2)
name_display = Label(gui, text=details_list[x][0])
name_display.grid(column=1, row=x 2)
# store the labels in the list
label_list.extend([row_display, name_display])
def delete_row():
try:
size = len(details_list)
idx = int(delete_row_entry.get()) - 1 # may raise exception
if size and 0 <= idx < size:
del details_list[idx]
# below line seems useless
#entries_count = counters['entries_count']
counters['total_entires'] -= 1
delete_row_entry.delete(0, 'end')
print_entries()
else:
print('row number is out of range' if size else 'empty list')
except ValueError as ex:
print(ex)
...