Python dictionary, list and for-loop bug

Question:

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?

Asked By: Daniel

||

Answers:

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.

Answered By: Unmitigated