如何在事件中获取小部件名称?
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()
在我的事件函数中,我想根据点击的标签做不同的事情。我难过的是,我只能得到被点击的小部件的标识符号,而不是名称。如果我能得到我所有小部件的标识符,那么我可以这样做:
def flipper(event):
if event.widget == switcher.identifier():
do stuff
但我也找不到如何获取指定小部件的 ID...
如何通过标识符 (event.widget()
) 获取小部件的名称?
或如何获取指定widget名称的标识符?
如果两者都不可能,那么我将不得不为每个标签创建一个不同的函数并绑定,希望这是不需要的大量工作。
编辑:
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()
快速而肮脏 - 您可以让函数检查切换器属性。
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'
获取不到widget赋值的变量名,比较没用。一个小部件可以分配给多个变量,或者根本 none。
获取标签文本
您可以访问实际的小部件,并且可以使用它来获取标签上的文本。您的示例显示所有标签都相同,因此这可能对您没有用:
def flipper(event):
print("label text:", event.widget.cget("text"))
使用自定义小部件名称
您还可以为小部件命名。您无法准确取回名称,但可以非常接近。例如,如果您创建这样的标签:
switcher = Label(main, name="switcher", bg='white', text="click here", font="-weight bold")
您可以通过拆分“.”来获取小部件的字符串表示形式。并取最后一个值:
def flipper(event):
print("widget name:", str(event.widget).split(".")[-1])
通过绑定传递名称
最后,您可以设置绑定,以便将名称发送到函数:
switcher.bind("<Button-1>", lambda event: flipper(event, "switcher"))
switcher1.bind("<Button-1>", lambda event: flipper(event, "switcher1"))
您可以使用event.widget
从点击的小部件中获取标准参数
示例:
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()
您可以为小部件分配自己的变量
switcher.extra = "Hello"
然后得到它
event.widget.extra
示例:
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()
您可以使用 lambda
将函数与参数绑定
bind("<Button-1>", lambda event:callback(event, "Hello"))
示例:
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()
我知道这是一个旧问题 post,但我遇到了同样的问题,我想我应该分享一个解决方案,以防有人感兴趣。您可以通过创建小部件的子类来为小部件命名。例如。 "Button" 是一个小部件。您可以制作一个继承自按钮的子部件 "MyButton",然后向其添加一个实例变量(例如名称、唯一 ID 等)
这是一个代码片段
class MyButton(Button):
def __init__(self, master = None, textVal = "", wName = ""):
Button.__init__(self, master, text = textVal)
self.widgetID = wName #unique identifier for each button.
当您想创建一个新的按钮小部件时,请使用
b = MyButton(.....),
代替
b = 按钮(.......)
这样,您就拥有了按钮的所有功能,外加唯一标识符。
我遇到了同样的问题,我发现简单的方法是使用绑定方法。
apparent name 属性 是私有的,但可以通过 _name 访问
如果您计划在运行时动态生成小部件,这将很有用
# 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()
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()
在我的事件函数中,我想根据点击的标签做不同的事情。我难过的是,我只能得到被点击的小部件的标识符号,而不是名称。如果我能得到我所有小部件的标识符,那么我可以这样做:
def flipper(event):
if event.widget == switcher.identifier():
do stuff
但我也找不到如何获取指定小部件的 ID...
如何通过标识符 (event.widget()
) 获取小部件的名称?
或如何获取指定widget名称的标识符?
如果两者都不可能,那么我将不得不为每个标签创建一个不同的函数并绑定,希望这是不需要的大量工作。
编辑:
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()
快速而肮脏 - 您可以让函数检查切换器属性。
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'
获取不到widget赋值的变量名,比较没用。一个小部件可以分配给多个变量,或者根本 none。
获取标签文本
您可以访问实际的小部件,并且可以使用它来获取标签上的文本。您的示例显示所有标签都相同,因此这可能对您没有用:
def flipper(event):
print("label text:", event.widget.cget("text"))
使用自定义小部件名称
您还可以为小部件命名。您无法准确取回名称,但可以非常接近。例如,如果您创建这样的标签:
switcher = Label(main, name="switcher", bg='white', text="click here", font="-weight bold")
您可以通过拆分“.”来获取小部件的字符串表示形式。并取最后一个值:
def flipper(event):
print("widget name:", str(event.widget).split(".")[-1])
通过绑定传递名称
最后,您可以设置绑定,以便将名称发送到函数:
switcher.bind("<Button-1>", lambda event: flipper(event, "switcher"))
switcher1.bind("<Button-1>", lambda event: flipper(event, "switcher1"))
您可以使用event.widget
从点击的小部件中获取标准参数
示例:
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()
您可以为小部件分配自己的变量
switcher.extra = "Hello"
然后得到它
event.widget.extra
示例:
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()
您可以使用 lambda
将函数与参数绑定
bind("<Button-1>", lambda event:callback(event, "Hello"))
示例:
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()
我知道这是一个旧问题 post,但我遇到了同样的问题,我想我应该分享一个解决方案,以防有人感兴趣。您可以通过创建小部件的子类来为小部件命名。例如。 "Button" 是一个小部件。您可以制作一个继承自按钮的子部件 "MyButton",然后向其添加一个实例变量(例如名称、唯一 ID 等)
这是一个代码片段
class MyButton(Button):
def __init__(self, master = None, textVal = "", wName = ""):
Button.__init__(self, master, text = textVal)
self.widgetID = wName #unique identifier for each button.
当您想创建一个新的按钮小部件时,请使用 b = MyButton(.....), 代替 b = 按钮(.......)
这样,您就拥有了按钮的所有功能,外加唯一标识符。
我遇到了同样的问题,我发现简单的方法是使用绑定方法。 apparent name 属性 是私有的,但可以通过 _name 访问 如果您计划在运行时动态生成小部件,这将很有用
# 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()