Home > Back-end >  tkinter create clickable labels in for loop
tkinter create clickable labels in for loop

Time:09-26

I want to create multiple clickable labels in a for-loop. The labels are structured grid-like with a row and col attribute. If I click the label, the row and col of the clicked label should be printed with the print_it() function.
The problem is if I click any label, the output is always the last defined row/col (2,2) in this case. How can I fix it, so the correct row/col gets printed?

Here is a code example to reproduce:

from tkinter import *


def print_it(row, col):
    print(row, col)


root = Tk()

sizex = 700
sizey = 400
posx = 0
posy = 0
root.wm_geometry("%dx%d %d %d" % (sizex, sizey, posx, posy))

canvas_area = Canvas(root)
canvas_area.grid(row=1, column=1)

labels = []
for row in range(3):
    for col in range(3):
        labels.append(Label(canvas_area, text=f"Row, Col: {row},{col}", bd=0))
        labels[-1].grid(row=row, column=col)

        labels[-1].bind(
            f"<Button-1>",
            lambda e: print_it(row, col),
        )

root.mainloop()

CodePudding user response:

The thing is you have made the labels to click to the row,col variable which at the end are always 2,2(or whatever the last value is after definition of loop).The solution I think is instead of passing row,col as args to print_it function pass the row and col of labels with:-

lambda e: print_it(labels[-1].grid_info()['row'],labels[-1].grid_info()['column'])

CodePudding user response:

I actually found another post which let me solve this problem: Python Tkinter: Bind function to list of variables in a for-loop
The correct definition of the bind function is this:

    labels[-1].bind(
        "<Button-1>",
        lambda event, row=row, col=col: print_it(row, col),
    )
  • Related