Search code examples
pythontkintertkinter-entry

With printing Entry´s text, last character is dismissed. How to fix?


I want to print the text of an Entry each time a new character is written. By doing this with binding and a command to the widget the last character isn't printed.

I guess that the parameter 'textvariable' is getting updated after binding command had been executed. How to fix this?

from tkinter import *
master = Tk()
var = StringVar()

def execute_e(key):
    print(var.get())

E = Entry(master, width=30, textvariable=var)
E.pack()
E.bind('<Key>', execute_e)

Solution

  • I feel like this is a question of event handler. When a key is typed, your code first register a key press and execute the bound command execute_e. Only after it has processed this and your event handler has return will it update the entry with the character and proceed to update the tkinter variable.

    Your print command therefore comes in before your variable have been updated and you print the previous version of your variable. If you try deleting a character from your entry, you'll see that you get the previous string with the character you have just erased.

    The easiest way around that problem for you is probably to bind the command to the tkinter variable rather than the keybind. Do so using trace when the variable is writen like so :

    var.trace('w', execute_e)
    

    There are also some methods to manipulate the event handler and decide in which order to execute commands. root.after_idle will execute a command when the code has nothing else to do (when it has computed everything else you asked it to do). Try out this version of your code :

    from tkinter import *
    master = Tk()
    var = StringVar()
    
    def execute_e(*key):
        def printy():
            print(var.get())
        master.after_idle(printy)
    
    E = Entry(master, width=30, textvariable=var)
    E.pack()
    E.bind('<Key>', execute_e)
    master.mainloop()