在 Tkinter Text 小部件被 Text 小部件绑定后,如何在 Tkinter Text 小部件中绑定自身事件? [英] How to bind self events in Tkinter Text widget after it will binded by Text widget?

查看:26
本文介绍了在 Tkinter Text 小部件被 Text 小部件绑定后,如何在 Tkinter Text 小部件中绑定自身事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Text 小部件类绑定之后绑定 self 事件,以便在调用我的绑定函数时更改小部件的文本.我的绑定,例如 self.text.bind("", self.callback),在 Text 小部件中的内容更改之前被调用.

I want to bind self events after Text widget class bindings, in order to change the text of the widget when my binding function is called. My binding, for example self.text.bind("<Key>", self.callback), is called before the content in Text widget changes.

推荐答案

在您的情况下发生的情况是您的打印值绑定发生在类绑定之前,并且实际上是类绑定接受用户输入并将其放入在小部件中.有几种方法可以解决这个问题.您可以绑定到 而不是 ,或者您可以使用内置的条目验证功能在每次按键时调用您的代码.使用该解决方案,您将获得所需的所有数据——更改前的值、更改后的值、按下的键等.

What is happening in your case is that your binding to print the value happens before the class binding, and it's the class binding that actually takes user input and puts it in the widget. There are several ways to solve this problem. You could bind to <KeyRelease> instead of <KeyPress>, or you could use the built-in entry validation features to have your code called on every key press. With that solution you'll be given all the data you need -- the value before the change, the value after the change, the key that was pressed, etc.

另一种选择是更改处理事件的顺序.由于您的问题专门询问如何更改订单,这就是我将要解决的问题.

Another choice is to change the order in which events are processed. Since your question specifically asked how to change the order, that is what I will address.

即使在您执行诸如 entry.bind(...) 之类的操作时绑定似乎与小部件相关联,但您实际上是将绑定分配给绑定标签"(或绑定标签").默认情况下,每个小部件都有一个与小部件名称相同的绑定标签.其他绑定标签包括小部件的类(例如Entry")、根窗口的路径(例如:.")和特殊标签all".小部件被分配了一组绑定标签,当接收到事件时,这些绑定标签会按顺序进行处理.默认顺序从最具体到最不具体:小部件、类、顶层、全部.

Even though a binding appears to be associated with a widget when you do something like entry.bind(...), you're actually assigning a binding to a "bind tag" (or "bindtag"). By default each widget has a bindtag that is the same as the name of the widget. Other bindtags include the class of a widget (for example, "Entry"), the path of the root window (eg: ".") and the special tag "all". Widgets are assigned a set of bindtags which are processed in order when an event is received. The default order goes from most- to least-specific: widget, class, toplevel, all.

有几种方法可以操作绑定标签以获得您想要的结果.一种选择是重新排列绑定标签的顺序.通过将表示小部件的绑定标签移到表示类的绑定标签之后,该类将在将事件传递给特定小部件之前对其进行处理.

There are a couple ways to manipulate the bindtags to get the result you desire. One choice is to rearrange the order of the bindtags. By moving the bindtag that represents the widget to be after the bindtag representing the class, the class will handle the event before passing it on to the specific widget.

另一种选择是在类绑定之后添加一个额外的绑定标签,然后将您的绑定放在这个标签上,而不是放在代表小部件的标签上.

Another choice is to add an additional bindtag that is after the class binding, and then put your bindings on this tag rather than on the tag that represents the widget.

为什么选择一个而不是另一个?通过重新排列顺序,您将影响该小部件上的所有绑定.如果您有许多绑定,并且其中一些依赖于顺序(例如,这样可以禁止某些键击),更改顺序可能会导致这些绑定停止工作.

Why choose one over the other? By rearranging the order you will affect all bindings on that widget. If you have many bindings and some depend on the order (so that the can, for example, disallow certain keystrokes), changing the order may cause those bindings to stop working.

通过引入新的绑定标签,您可以选择哪些绑定发生在类绑定之前,哪些发生在之后.

By introducing a new bindtag, you can choose which bindings happen before class bindings and which happen after.

在下面的代码中,我创建了三个条目小部件.第一个使用默认的绑定标签集(在示例中明确设置,尽管它们与默认值相同).第二个改变了顺序,第三个引入了一个额外的绑定标签.运行代码,然后在焦点位于每个窗口中时按下一个键.请注意,在第一个条目小部件中,绑定似乎总是落后一个字符.同样,这是因为小部件绑定发生在类绑定将字符放入小部件之前.

In the following code I create three entry widgets. The first uses the default set of bindtags (explicitly set in the example, though they are identical to the default). The second changes the order, and the third introduces an additional bindtag. Run the code then press a key while the focus is in each window. Notice that in the first entry widget the binding always seems to be one character behind. Again, this is because the widget binding happens before the class binding puts the character into the widget.

在第二个和第三个示例中,绑定发生在类绑定之后,因此函数会看到小部件的变化.

In the second and third examples, the binding happens after the class binding so the function sees the change in the widgets.

import Tkinter

def OnKeyPress(event):
    value = event.widget.get()
    string="value of %s is '%s'" % (event.widget._name, value)
    status.configure(text=string)

root = Tkinter.Tk()

entry1 = Tkinter.Entry(root, name="entry1")
entry2 = Tkinter.Entry(root, name="entry2")
entry3 = Tkinter.Entry(root, name="entry3")

# Three different bindtags. The first is just the default but I'm
# including it for illustrative purposes. The second reverses the
# order of the first two tags. The third introduces a new tag after
# the class tag.
entry1.bindtags(('.entry1', 'Entry', '.', 'all'))
entry2.bindtags(('Entry', '.entry2', '.', 'all'))
entry3.bindtags(('.entry3','Entry','post-class-bindings', '.', 'all'))

btlabel1 = Tkinter.Label(text="bindtags: %s" % " ".join(entry1.bindtags()))
btlabel2 = Tkinter.Label(text="bindtags: %s" % " ".join(entry2.bindtags()))
btlabel3 = Tkinter.Label(text="bindtags: %s" % " ".join(entry3.bindtags()))
status = Tkinter.Label(anchor="w")

entry1.grid(row=0,column=0)
btlabel1.grid(row=0,column=1, padx=10, sticky="w")
entry2.grid(row=1,column=0)
btlabel2.grid(row=1,column=1, padx=10, sticky="w")
entry3.grid(row=2,column=0)
btlabel3.grid(row=2,column=1, padx=10)
status.grid(row=3, columnspan=2, sticky="w")

# normally you bind to the widget; in the third case we're binding
# to the new bindtag we've created
entry1.bind("<KeyPress>", OnKeyPress)
entry2.bind("<KeyPress>", OnKeyPress)
entry3.bind_class("post-class-bindings", "<KeyPress>", OnKeyPress)

root.mainloop()

这篇关于在 Tkinter Text 小部件被 Text 小部件绑定后,如何在 Tkinter Text 小部件中绑定自身事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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