1

Consider the following code:

#!/usr/bin/env python3

from tkinter import *
from tkinter.ttk import *

root = Tk()

entry = Entry(root)
entry.bind('<Key>', lambda e: print(entry.get()))
entry.grid()

Button(text="Close", command=root.destroy).grid()

root.mainloop()

It prints the text in the entry input box every time a key is pressed, so why does it print the text as it was one key before?

I suspect it is because the entry.get() is run before the key is added to the input box. Is there a way around this?


Example:

When I type the following, one key at a time:

Python

the following is printed

Pytho
kiri
  • 2,522
  • 4
  • 26
  • 44

2 Answers2

2

I was trying to monitor the Entry widget in realtime.

Steven's answer to this question provided a better method than binding to all keys:

Use a Tkinter.StringVar to track the value of the Entry widget. You can validate the value of the StringVar by setting a trace on it.

In case anyone wants it, the following is the original example code modified to use StringVar:

#!/usr/bin/env python3

from tkinter import *
from tkinter.ttk import *

root = Tk()

text_var = StringVar()
entry = Entry(root, textvariable=text_var)
text_var.trace('w', lambda nm, idx, mode: print(text_var.get()))
entry.grid()

Button(text="Close", command=root.destroy).grid()

root.mainloop()
Community
  • 1
  • 1
kiri
  • 2,522
  • 4
  • 26
  • 44
  • This doesn't answer the question of `why`, it only provides a workaround. That's useful, but it doesn't really answer the question. – Bryan Oakley Dec 03 '13 at 12:05
  • @BryanOakley "I suspect it is because the entry.get() is run before the key is added to the input box. Is there a way around this?" [ref](http://stackoverflow.com/q/20347023/2734389) – kiri Dec 04 '13 at 00:34
  • yes, the tkinter binding system is very powerful. For more information see http://stackoverflow.com/a/11542200/7432 and http://stackoverflow.com/questions/2458026/python-gui-events-out-of-order/2472992#2472992 – Bryan Oakley Dec 04 '13 at 01:16
1

The title of the question is "Why is Entry.get() one key behind?"

The short answer is this: any binding you create on a widget happens before the default behavior of inserting a character into the widget. The reason is that you may want to alter or prevent the default behavior, which would be impossible if your binding fired after it happened (you could undo the default behavior, but you couldn't prevent it).

There is a proper solution. The long answer is in this stackoverflow answer: https://stackoverflow.com/a/11542200/7432 (from the question Basic query regarding bindtags in tkinter). Even more information is in this stackoverflow answer: python gui events out of order (from the question python gui events out of order)

Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685