-1

Consider the following simple code:

from tkinter import *

startingWindow = Tk()

entry = Entry(startingWindow)
entry.grid(row=0, column=0)

def writeWhatYouGet():        
    print((entry.get()).strip())

entry.bind('<Key>', lambda event:writeWhatYouGet())
startingWindow.mainloop()

I expect that when I type "1", I get "1" printed right away. However, I only get "1", when I press the second key, which is "2" in this case.

Like the following:

enter image description here

and the printed output is like

1
12
123

However I expect the output to be like:

1
12
123
1234

How I can solve this so I get what I write right away?

AhmedWas
  • 1,205
  • 3
  • 23
  • 38
  • 2
    Related: [python gui events out of order](https://stackoverflow.com/q/2458026/3714930) – fhdrsdg Jul 19 '18 at 11:47
  • @downvoter, please comment when downvoting. Beind duplicate doesn't deserve downvoting, just marking as dublicate. – AhmedWas Jul 19 '18 at 14:35
  • @AhmedWas Down-votes can be for many reason. You should not assume the reason is specifically for the duplicate post (though people do down-vote for this reason). For example in your question you only describe a problem you ran into but do not show any attempt to solve the problem or show what you have tried to fix it on your own before posting. So I would argue the down-vote is for this lack of effort instead of the duplicate post. (does't matter if you did try something to fix it your post does not show it) – Mike - SMT Jul 20 '18 at 12:44

2 Answers2

1

I don't understand why your code does not work, but I can offer a solution that does work.

Associate the entry with a StringVar and then trace all changes to the StringVar:

from tkinter import *

startingWindow = Tk()

text = StringVar()
entry = Entry(startingWindow, textvariable=text)
entry.grid(row=0, column=0)

def writeWhatYouGet(*args):
    print(text.get())

text.trace_add("write", writeWhatYouGet)   # Trace changes to StringVar "text"

startingWindow.mainloop()

Reference: The Variable Classes (BooleanVar, DoubleVar, IntVar, StringVar)

figbeam
  • 7,001
  • 2
  • 12
  • 18
  • 2
    By the way, the `text.trace("w", writeWhatYouGet)` syntax is deprecated in python 3.6 (https://docs.python.org/3/whatsnew/3.6.html), the new syntax is `text.trace_add("write", writeWhatYouGet)`. – j_4321 Jul 19 '18 at 12:24
1

This behavior happens because the class binding that inserts the key in the Entry is executed after the widget's binding. Therefore, when writeWhatYouGet is executed, the Entry does not contains\ the new key yet. You can check this with the following code:

from tkinter import *

startingWindow = Tk()

entry = Entry(startingWindow)
entry.grid(row=0, column=0)

def writeWhatYouGet():        
    print('bind', (entry.get()).strip())

def writeWhatYouGet2():        
    print('bind_class', (entry.get()).strip())

entry.bind('<Key>', lambda event:writeWhatYouGet())
entry.bind_class('Entry', '<Key>', lambda event:writeWhatYouGet2(), True)
startingWindow.mainloop()

To solve this problem, you can use figbeam solution or you can use the validate command option of the Entry:

from tkinter import *

startingWindow = Tk()


def writeWhatYouGet(text):        
    print(text.strip())
    return True

validatecmd = startingWindow.register(writeWhatYouGet)

entry = Entry(startingWindow, validate='key', validatecommand=(validatecmd, '%P'))
# %P means that the value the text will have if the change is allowed is passed to validatecmd.
entry.grid(row=0, column=0)

startingWindow.mainloop()

More details about entry validation: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html

j_4321
  • 15,431
  • 3
  • 34
  • 61