'How to get widget name in event?

from tkinter import *

main = Tk()

def flipper(event):
    # I'd like to do this:
    #if widgetname == switcher:
        #do stuff
    #if widgetname == switcher1:
        #do stuff
    return

switcher = Label(main, bg='white', text="click here", font="-weight bold")
switcher.grid()
switcher.bind("<Button-1>", flipper)


switcher1 = Label(main, bg='white', text="click here", font="-weight bold")
switcher1.grid()
switcher1.bind("<Button-1>", flipper)

switcher2 = Label(main, bg='white', text="click here", font="-weight bold")
switcher2.grid()
switcher2.bind("<Button-1>", flipper)

switcher3 = Label(main, bg='white', text="click here", font="-weight bold")
switcher3.grid()
switcher3.bind("<Button-1>", flipper)

switcher4 = Label(main, bg='white', text="click here", font="-weight bold")
switcher4.grid()
switcher4.bind("<Button-1>", flipper)

switcher5 = Label(main, bg='white', text="click here", font="-weight bold")
switcher5.grid()
switcher5.bind("<Button-1>", flipper)


main.mainloop()

In my event function I'd like to do different things based on the label that is clicked. What im stumped on is that I can only get the identifier number of the widget that is clicked, not the name. If I could get the identifier of all my widgets then I could do:

def flipper(event):
    if event.widget == switcher.identifier():
           do stuff

but I can't find how to get the id of a specified widget either...

How can I get the name of a widget by its identifier (event.widget())?

Or how can I get the identifier of a specified widget name?

If neither are possible, then I'd have to make a different function and bind for each label which is a lot of work that hopefully is not necessary.


Edit:

from tkinter import *

main = Tk()

def flipper(event, switch):
    if switch.widget == 's1':
        print("got it")

switcher = Label(main, bg='white', text="click here", font="-weight bold")
switcher.grid()
switcher.bind("<Button-1>", flipper)
switcher.widget = 's1'


main.mainloop()


Solution 1:[1]

You can use event.widget to get standard parameters from clicked widget

example:

import tkinter as tk

def callback(event):
    print(event.widget['text'])

main = tk.Tk()

switcher = tk.Label(main, text="click here")
switcher.grid()
switcher.bind("<Button-1>", callback)

main.mainloop()

You can assign own variables to widgets

switcher.extra = "Hello"

and then get it

event.widget.extra

example:

import tkinter as tk

def callback(event):
    print(event.widget['text'])
    print(event.widget.extra)

main = tk.Tk()

switcher = tk.Label(main, text="click here")
switcher.grid()
switcher.bind("<Button-1>", callback)
switcher.extra = "Hello"

main.mainloop()

You can use lambda to bind function with arguments

bind("<Button-1>", lambda event:callback(event, "Hello"))

example:

import tkinter as tk

def callback(event, extra):
    print(event.widget['text'])
    print(extra)

main = tk.Tk()

switcher = tk.Label(main, text="click here")
switcher.grid()
switcher.bind("<Button-1>", lambda event:callback(event, "Hello"))

main.mainloop()

Solution 2:[2]

I had the same issue I found easy way was to use bind method. apparent name property is private but can be accessed via _name This is useful if you plan to generate widgets dynamically at runtime

# Import Module
from tkinter import *
 
# create root window
root = Tk()
 
# root window title and dimension
root.title("Welcome to Test window")
# Set geometry (widthxheight)
root.geometry('350x200')

#adding a label to the root window
lbl = Label(root, text = "Press a button")
lbl.grid()

#define mouse up event
def mous_up(ev:Event):
    #get calling widget from event
    sender:Button = ev.widget
    
    #set label text
    lbl.configure(text = sender._name + "  up")
    
    #read foreground color from button 
    #If red make green, else make red
    if sender.cget('fg') == "red":
        #normal color
        sender.configure(fg='lime')
        #mouse over color
        sender.configure(activeforeground='green')
    else:
        #normal color
        sender.configure(fg="red")
        #mouse over color
        sender.configure(activeforeground='darkred')

#define mouse down event
def mous_down(ev:Event):
    lbl.configure(text = str(ev.widget._name) + " down")
 
# button widget with red color text
# inside
btn = Button(root, text = "Click me" ,
             fg = "red",name = "button-A")

#bind mouse up and mouse down events
btn.bind('<ButtonRelease-1>',mous_up)
btn.bind('<Button-1>',mous_down)

# set Button grid
btn.grid(column=0, row=1)

#Create another button
btn =  Button(root, text = "Click me2" ,
             fg = "red",name="button2")

#bind mouse up and mouse down events
btn.bind('<ButtonRelease-1>',mous_up)
btn.bind('<Button-1>',mous_down)

#absolute placement of button instead of 
#using grid system
btn.place(x=50,y=100)
 
# all widgets will be here
# Execute Tkinter
root.mainloop()

Solution 3:[3]

Quick and dirty - you could have the function check a switcher attribute.

def flipper(event, switch):
    if switch.widget == 's1':
        do_stuff
        return stuff
    if switch.widget == 's2':
        do_stuff
        return stuff

switcher1.widget = 's1'
switcher2.widget = 's2'

Solution 4:[4]

I know this is an old post, but I had the same problem and I thought I should share a solution in case anyone is interested. You can give your widget a name by creating a subclass of the widget. E.g. "Button" is a widget. You can make a child widget "MyButton" which inherits from button and then add an instance variable to it (e.g. name, uniqueID etc.)

Here is a code snippet

class MyButton(Button):
    def __init__(self, master = None, textVal = "", wName = ""):
        Button.__init__(self, master, text =  textVal)
        self.widgetID = wName #unique identifier for each button. 

When you want to create a new button widget, use b = MyButton(.....), instead of b = Button(.......)

This way, you have all the functionality of a button, plus the unique identifier.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 furas
Solution 2 David Myers
Solution 3
Solution 4 Alex