0

I'm trying to create a dynamically-updating searchbox and instead of polling the the entry widget every x milliseconds, I am trying to use keyboard bindings to get the contents of the entry widget whenever a key on the keyboard is pressed:

from tkinter import *
root = Tk()
def callback():
    result = searchbox.get()
    print(result)
    #do stuff with result here
searchbox = Entry(root)
searchbox.pack()
searchbox.bind("<Key>", lambda event: callback())
root.mainloop()

my problem is that searchbox.get() is always executed before the key the user pressed is added to the searchbox, meaning the result is the content of the searchbox BEFORE the key was pressed and not after. For example if I were to type 'hello' in the searchbox, I would see the following printed:

>>>
>>> h
>>> he
>>> hel
>>> hell

Thanks in advance.

James Batchelor
  • 99
  • 1
  • 1
  • 14

1 Answers1

1

There's no need to use bindings. You can associate a StringVar with the widget, and put a trace on the StringVar. The trace will call your function whenever the value changes, no matter if it changes from the keyboard or the mouse or anything else.

Here's your code, modified to use a variable with a trace:

from tkinter import *
root = Tk()
def callback(*args):
    result = searchbox.get()
    print(result)
    #do stuff with result here
var = StringVar()
searchbox = Entry(root, textvariable=var)
searchbox.pack()
var.trace("w", callback)
root.mainloop()

For information about the arguments passed to the callback see What are the arguments to Tkinter variable trace method callbacks?

For a better understanding of why your bindings seem to always be one character behind, see the accepted answer to Basic query regarding bindtags in tkinter

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