我有一系列按钮的常见回调。 一旦调用了回调,我想通过其先前分配的名称来识别调用者。 但我无法在Tkinter文档中弄清楚我是如何做到这一点的。有什么想法吗?
我的节目约为
def callback(event):
event.widget['text'] # 'name' does not work so
# I have to use the label of the button now, but it is a dirty solution.
root.bind("<Button-1>", cb_button)
我需要这些名称,因为我使用pytkgen从JSON加载GUI。
更新
Justin的解决方案看起来不错,但为什么以下代码始终9
打印,无论点击哪个按钮?
def cb_button(i):
print i
buttons = [('btn'+str(i), i) for i in range(10)]
for (b, i) in buttons:
root.button(b, lambda: cb_button(i))
答案 0 :(得分:3)
窗口小部件的winfo_name()方法返回窗口小部件的名称。它通常是一个8位数字,表示为字符串,即:'40123211'如果你有一个事件对象,evt,那么使用:evt.widget.winfo_name()
在问题的正文中,你会问一些不同的东西:“我怎么知道哪个按钮调用了一个共同的回调函数”
使用lambda函数将唯一值传递给公共回调:
根据您问题的更新,我想我理解了这个问题。您有一个JSON文件,用于通过pytkgen创建Tkinter接口。在这个JSON文件中有几个按钮的定义,每个按钮都有一个唯一的名称。在为这些按钮分配命令时,它们都被赋予相同的回调,但回调需要知道哪个按钮启动了呼叫,并且您希望通过名称来执行此操作。这是对的吗?
如果是这样,我猜你正在创建这样的回调分配(非常通用的例子,假设root
是通过调用tkgen.gengui.TkJson
返回的接口root返回的路径JSON文件):
root.button("name1", callback)
root.button("name2", callback)
...
但这并没有给你你想要的名字。传递名称的一种方法是创建一个lambda
,将按钮名称传递给回调函数。然后回调分配看起来像这样:
root.button("name1", lambda:callback("name1"))
root.button("name2", lambda:callback("name2"))
...
然后你的回调定义可能如下所示:
def callback(name):
if name == "name1":
# Do something in here
elif name == "name2":
# Do something else in here
...
更新:如果您在循环内创建按钮,则需要修改lambda定义以将所需的循环变量存储为关键字默认值。否则,循环变量的最终值将应用于所有按钮。
def cb_button(i):
print i
buttons = [('btn'+str(i), i) for i in range(10)]
for (b, i) in buttons:
root.button(b, lambda x=i: cb_button(x))
向窗口小部件对象添加属性
另一个解决方案是可以在回调函数中检查按钮小部件对象的属性。 (这个例子使用Tkinter)
but1 = Tkinter.Button(root, text="Sync", width=10)
but1.bind("<Button-1>", doButton)
but1.myId = "this"
but2 = Tkinter.Button(root, text="Sync", width=10)
but2.bind("<Button-1>", doButton)
but2.myId = "that"
but2.otherStuff = "anything"
def doButton(evt):
if evt.widget.myId == "this":
print("This")
else:
print("That "+evt.widget.otherStuff)
答案 1 :(得分:0)
我不记得如何获取名称,但您始终可以使用
列出所有内容print dir(event)
或
print dir(event.widget)
答案 2 :(得分:0)
commmon方式是使用一个公共函数,但不是完全相同的回调(通过lambda闭包,如Justin's answer指出的那样)。
依靠工具包的内部有两个不完美的替代方案:
_name
widgets
字典,您可以迭代以找回您的小部件名称(name = [k for k, v in root.widgets.iteritems() if v == event.widget][0]
)。为了更好地进行代码分离,您可以使用event.widget._nametowidget('.')
值得注意的是,这些解决方案不适用于不向其回调提供事件的按钮command
。并且优先通过完成对按钮的绑定动作
command
因为它实现了按钮的通常行为(释放时的动作,你可以通过离开按钮来中止......)。