Tkinter, Entry widget, is detecting input text possible?

If you just need to do simple things without using trace module you can try

    def objchangetext(self, textwidget):
        print(textwidget.get())  #print text out to terminal

    text1 = tk.Entry(tk.Tk()) 
    text1.bind("<KeyRelease>", lambda event, arg=(0): objchangetext(text1)) 

Yes. There are a few different ways to do this, in fact.

You can create a StringVar, attach it to the Entry, and trace it for changes; you can bind all of the relevant events; or you can add a validation command that fires at any of several different points in the sequence. They all do slightly different things.

When a user types 4, there's a key event with just the 4 in it (which doesn't let you distinguish whether the user was adding 4 to the end, or in the middle, or replacing a whole selected word, or…), and then a modification event is fired with the old text,* and then the "key" or "all" validation function is called with the (proposed) new text, and the variable is updated with the (accepted) new text (unless the validation function returned false, in which case the invalidcommand is called instead).


I don't know which one of those you want, so let's show all of them, and you can play around with them and pick the one you want.

import Tkinter as tk

root = tk.Tk()

def validate(newtext):
    print('validate: {}'.format(newtext))
    return True
vcmd = root.register(validate)

def key(event):
    print('key: {}'.format(event.char))

def var(*args):
    print('var: {} (args {})'.format(svar.get(), args))
svar = tk.StringVar()
svar.trace('w', var)

entry = tk.Entry(root,
                 textvariable=svar, 
                 validate="key", validatecommand=(vcmd, '%P'))
entry.bind('<Key>', key)
entry.pack()
root.mainloop()

The syntax for variable trace callbacks is a bit complicated, and not that well documented in Tkinter; if you want to know what the first two arguments mean, you need to read the Tcl/Tk docs, and understand how Tkinter maps your particular StringVar to the Tcl name 'PY_VAR0'… Really, it's a lot easier to just build a separate function for each variable and mode you want to trace, and ignore the args.

The syntax for validation functions is even more complicated, and a lot more flexible than I've shown. For example, you can get the inserted text (which can be more than one character, in case of a paste operation), its position, and all kinds of other things… but none of this is described anywhere in the Tkinter docs, so you will need to go the Tcl/Tk docs. The most common thing you want is the proposed new text as the argument, and for that, use (vcmd, '%P').


Anyway, you should definitely play with doing a variety of different things and see what each mechanism gives you. Move the cursor around or select part of the string before typing, paste with the keyboard and with the mouse, drag and drop the selection, hit a variety of special keys, etc.


* I'm going to ignore this step, because it's different in different versions of Tk, and not very useful anyway. In cases where you really need a modified event, it's probably better to use a Text widget and bind <<Modified>>.


Every time you press a key inside a Tkinter window, a Tkinter.Event instance is created. All you need to do is access that instance. Here is a simple script that demonstrates just how:

from Tkinter import Tk, Entry

root = Tk()

def click(key):
    # print the key that was pressed
    print key.char

entry = Entry()
entry.grid()
# Bind entry to any keypress
entry.bind("<Key>", click)

root.mainloop()

key (being a Tkinter.Event instance) contains many different attributes that can be used to get almost any type of data you want on the key that was pressed. I chose to use the .char attribute here, which will have the script print what each keypress is.