How to get widget name in event

2020-07-23 07:12发布

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 cant 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()

4条回答
何必那么认真
2楼-- · 2020-07-23 07:30

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()
查看更多
趁早两清
3楼-- · 2020-07-23 07:32

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'
查看更多
神经病院院长
4楼-- · 2020-07-23 07:35

You can't get the variable name that the widget is assigned to, that would be relatively useless. A widget could be assigned to more than one variable, or none at all.

Getting the label text

You have access to the actual widget, and you can use that to get the text that is on the label. Your example shows that all labels are the same, so this might not be useful to you:

def flipper(event):
    print("label text:", event.widget.cget("text"))

Using a custom widget name

You can also give a widget a name. You can't get back precisely the name, but you can come very close. For example, if you create a label like this:

switcher = Label(main, name="switcher", bg='white', text="click here", font="-weight bold")

You can get the string representation of the widget by splitting on "." and taking the last value:

def flipper(event):
    print("widget name:", str(event.widget).split(".")[-1])

Passing a name via the binding

Finally, you can set up your bindings such that the name is sent to the function:

switcher.bind("<Button-1>", lambda event: flipper(event, "switcher"))
switcher1.bind("<Button-1>", lambda event: flipper(event, "switcher1"))
查看更多
5楼-- · 2020-07-23 07:40

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.

查看更多
登录 后发表回答