使用Tkinter控制回调的顺序 [英] Controlling Order of Callbacks with Tkinter

查看:128
本文介绍了使用Tkinter控制回调的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短版本:是否可以控制在Tkinter中处理与不同小部件关联的回调的顺序?

Short version: Is there a way to control the order in which callbacks associated with different widgets are handled in Tkinter?

更长版本:我一直在使用以下命令在测试和学习Tkinter的同时使用IDLE程序:

Longer version: I have been using the following program in IDLE while testing out and learning Tkinter:

import Tkinter
guiRoot = Tkinter.Tk()
hWindow = Tkinter.Frame(guiRoot)
hWindow.grid(); x = 0; y = 0
et1 = Tkinter.Entry(hWindow)
et2 = Tkinter.Entry(hWindow)

def ut(x, y, event):
    print "X",x,", Y:",y
    print "Args:", 
    print "Widget:",event.widget.get()
    print

def Tkquit():
    print "Leaving program..."

et1 = Tkinter.Entry(hWindow)
et2 = Tkinter.Entry(hWindow)
eb = Tkinter.Button(hWindow, command=Tkquit, text="Send")
et1.grid(column=x, row=y)
et1.bind("<FocusOut>", lambda event, x1=x, y1=y:ut(x1, y1, event))
y = y + 1; et2.grid(column=x, row=y)
et2.bind("<FocusOut>", lambda event, x1=x, y1=y:ut(x1, y1, event))
y = y + 1
eb.grid(column=x, row=y)
guiRoot.mainloop()

当我从一个Entry字段移到另一个字段时,将调用ut()。当我单击按钮时,收到消息正在退出程序...(稍后将在例程中退出代码),但是文本小部件中没有消息只是失去了焦点。

When I move from one Entry field to the other, ut() is called. When I click on the Button, I get the message "Leaving program..." (which will later have quit code in the routine), but there is no message from the text widget that just lost focus.

这使我想到两个问题:

1)为什么不调用Entry字段的回调?

1) Why isn't the callback for the Entry field being called?

而且,这也暗示,如果我希望该按钮退出应用程序,则是我希望其他回调在该按钮的回调之前完成。所以:

And, also, implied, if I want that button to quit the application, is that I want other callbacks to be completed before the one from that button. So:

2)如何控制Tkinter调用回调的顺序?

2) How can I control the order in which callbacks are called by Tkinter?

推荐答案

当您按Exit时,不会调用< FocusOut> 事件的原因是因为输入小部件不会失去焦点。默认情况下,单击Tkinter按钮不会使其焦点。但是,如果使用 ttk.Button ,它会确实窃取焦点,因此将调用您的回调。我个人认为这是按钮的ttk实现中的一个错误,但是多年来一直如此。

The reason your <FocusOut> event doesn't get called when you press exit is because the entry widget doesn't lose focus. By default, Tkinter buttons don't get focus when you click on them. However, if you use a ttk.Button, it does steal focus, so your callback will be called. Personally I think that's a bug in the ttk implementation of buttons, but it's been that way for years.

无论哪种情况,您都可以将绑定添加到按钮上,这将导致它们在单击按钮时失去焦点。这样做将导致任何< FocusOut> 事件在先前具有焦点的窗口小部件上触发。通常这是不需要的,但Tkinter可为您提供这种灵活性。

In either case, you can add bindings to buttons which will cause them to steal focus when you click on them. Doing so will cause any <FocusOut> events to fire on the widget that previously had focus. Normally this isn't desired but Tkinter gives you that flexibility.

例如,将其添加到您的代码中,以在单击$ < FocusOut> 事件时将其触发按钮:

For example, add this to your code to get the <FocusOut> event to fire when you click the button:

# force the button to steal focus when clicked
eb.bind("<1>", lambda event: eb.focus_set())

您无法控制事件的处理顺序,因为事件是按照事件发生的顺序进行处理的。为了使工具箱执行其他任何操作将是错误的。我认为您会发现,一旦您对Tkinter的工作方式有了更好的了解,就无需乱序处理事件。

You can't control the order in which events are processed, because events are processed in the order that they occur. For a toolkit to do anything else would be wrong. I think you'll find that once you have a better understanding of how Tkinter works, you won't need to process events out of order.

这篇关于使用Tkinter控制回调的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆