Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic query regarding bindtags in tkinter

Tags:

python

tkinter

In the given example from this post, it was mentioned that if default bindtags are used then event value will not be visible inside definition (there will be lag by one).

There was some explanation regarding class binding.
I am a beginner, so would like to understand the detailed reason.
Can some please explain why it was not working in first case and was working in second case (when order of bindtags is modified).

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")

entry1.bindtags(('.entry1', 'Entry', '.', 'all'))
entry2.bindtags(('Entry', '.entry1', '.', 'all'))
entry3.bindtags(('.entry1','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")
entry1.bind("<KeyPress>", OnKeyPress)
entry2.bind("<KeyPress>", OnKeyPress)
entry3.bind_class("post-class-bindings", "<KeyPress>", OnKeyPress)

root.mainloop()
like image 437
sarbjit Avatar asked Jul 18 '12 12:07

sarbjit


People also ask

What is bind function in Tkinter?

In Tkinter, bind is defined as a Tkinter function for binding events which may occur by initiating the code written in the program and to handle such events occurring in the program are handled by the binding function where Python provides a binding function known as bind () where it can bind any Python methods and functions to the events.

What is an instance-level binding In Tkinter?

This is called an instance-level binding. Tkinter also allows you to bind an event to all the instances of a widget. For example, you can bind the event to all the textboxes in a program: By the way, you use the Entry widget to create a textbox in Tkinter.

How do I Break a tag In Tkinter?

Tkinter will check each tag in order to see if there's a binding that matches the event. If it finds one, it will execute the binding and then continue to the next tag, until it runs out of tags or one of the bound functions returns the string "break". You press the "x" key.

How to unbind the event from the BTN button In Tkinter?

By the way, you use the Entry widget to create a textbox in Tkinter. This is called class-level binding because you bind the event to a class instead of an instance. Sometimes, you may want to undo the effect of an earlier binding. To do it, you can use the unbind () method: The following example unbinds the event from the btn button:


1 Answers

When you do a binding on a widget, you aren't actually binding to a widget per se. When you do mywidget.bind(...), what is actually happening is that the binding is associated with a bind tag with the same name as the widget.

When an event is detected, Tkinter first figures out which widget intercepted the event. This widget will have a list of zero or more (by default: four) bind tags associated with it. Tkinter will check each tag in order to see if there's a binding that matches the event. If it finds one, it will execute the binding and then continue to the next tag, until it runs out of tags or one of the bound functions returns the string "break".

The sequence looks something like this:

  1. You press the "x" key. At this point the "x" hasn't been inserted anywhere
  2. Tkinter gets the bind tags for the widget that has the keyboard focus.
  3. By default the first bind tag is the widget itself. Is there a binding on that tag? If so, execute it. For example, you might print the contents of the widget. Because no other bindings have fired yet, the "x" will not be part of the contents.
  4. If the bound function returns "break" then no more event processing is done. The "x" will not get inserted into the widget.
  5. If the widget did not return "break", tkinter proceeds to the next bind tag.
  6. By default, the next bind tag is the widget class. Is there a binding on the class that matches this event (a keypress of the letter "x")?
  7. In this case the class does have a binding for this event, which is to actually insert the "x" into the widget. Until this point, the "x" still hasn't been inserted into the widget. After this binding, however, if you did a print of the contents you would see the "x"
  8. Processing continues in this manner until all bind tags have been processed.

Based on the ongoing discussion in the comment section, it appears this is still unclear. I'll try to make this as simple as possible:

It is the class binding which copies a character from the in-memory event object to the widget and thus causing it to appear on screen. Before the class binding fires, the character will not appear in the widget. After the class binding it will be in the widget.

like image 123
Bryan Oakley Avatar answered Oct 19 '22 12:10

Bryan Oakley