I’m trying to show a list of elements from a data set in a tkinter window. I want to able to manipulate the elements, by highlighting, deleting etc.
I have this code:
from tkinter import *
window = Tk()
window.geometry("100x100")
#data from API
data_list = [
["1", "Lorem"],
["2", "Lorem"],
["3", "Lorem"],
["4", "Lorem"]
]
#create selectable rectangles from data_list with delete buttons
rectangles = {}
delete_buttons = {}
def CreateRectangles():
i = 0
for data in data_list:
rectangles[i] = Canvas(window, bg="#BFBFBF", height=15, width=80)
rectangles[i].place(x=19, y=20.0 + (i * 19))
rectangles[i].create_text(5.0, 1.0, anchor="nw", text=str(f'#{data[0]}:{data[1]}'))
delete_buttons[i] = Label(window, text="X ", bg="#D9D9D9")
delete_buttons[i].place(x=6, y=20.0 + (i * 19))
i += 1
CreateRectangles()
#highlight clicked rectangle
def RectangleClick(e, arg):
#reset how all rectangles look
for i in rectangles:
rectangles[i].config(bg="#BFBFBF")
#highlight the one clicked
rectangles[arg].config(bg="#999999")
for key in rectangles:
rectangles[key].bind("<ButtonPress-1>", lambda event, arg=key: RectangleClick(event, arg))
#delete button action
def DeleteClick(e, arg):
# delete all rectangles and buttons from window
for rectangle in rectangles:
rectangles[rectangle].place_forget()
for delete in delete_buttons:
delete_buttons[delete].destroy()
# delete all rectangles and buttons from dictionary
rectangles.clear()
delete_buttons.clear()
# delete the specific data from de data_list
data_list.pop(arg)
# re do everything but now the data list has one less item
CreateRectangles()
for num in delete_buttons:
delete_buttons[num].bind("<ButtonPress-1>", lambda event, arg=num: DeleteClick(event, arg))
window.mainloop()
It only works the first time. For example, if I delete an item, it doesn’t do anything else.
What’s wrong?
>Solution :
Move all the code that binds event handlers inside the CreateRectangles method. Since all the previous rectangles are destroyed, the event handlers need to be attached again.