1

I have a list of n Entry widgets. The user should be able to type only the following charaters: "V", "F", " ". If the user types one of those characters, the focus should pass from Entry #x to Entry #x+1, otherwise the focus should stay where it is (on Entry #x) and the input should be discarded.

I am not able to discard the wrong input: if the user presses a key different from those allowed, the Entry field get that key, but the command .delete(0,END) doesn't work, as the widget itself hasn't yet memorized the key pressed.

How could I do?

zar
  • 113
  • 1
  • 7

2 Answers2

7
import Tkinter as tk

def keyPress(event):
    if event.char in ('V', 'F', ' '):
        print event.char
    elif event.keysym not in ('Alt_r', 'Alt_L', 'F4'):
        print event.keysym
        return 'break'


root = tk.Tk()
entry = tk.Entry()
entry.bind('<KeyPress>', keyPress)
entry.pack()
entry.focus()

root.mainloop()

You can easily break up the statement so it will go to a different form based on the key.

The event.keysym part is in there so you can ALT-F4 to close the app when you're in that widget. If you just else: return 'break' then it will capture all other keystrokes as well.

This also is a case sensitive capture. If you want case insensitive, just change it to event.char.upper()

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • Thank you, I was missing the "return 'break'" part. If I insert another linea before it (even a simple print statement), it doesn't work. – zar Aug 13 '10 at 18:43
  • 1
    @zar, You're welcome - `return 'break'` is how you stop Tkinter events from propagating (i.e. button presses, etc.). – Wayne Werner Aug 13 '10 at 18:45
  • Actually, what I said isn't true. If before the "break" I inserted another line, which calls the .get() statement over the Entry widget. That call was messing up everything. Thanks again. – zar Aug 13 '10 at 19:02
  • I have another question: how can I get the value of the Entry field? A line like x=entry.get() doesn't give the correct value, if the cursor is still on the entry field. – zar Aug 16 '10 at 13:28
  • (I will post it as a separate question) – zar Aug 16 '10 at 15:40
5

Using the validate and validatecommand options, this creates a tk.Entry which accepts characters in 'VF ' only, but can tell you which key is pressed and what the value of the entry currently is:

import Tkinter as tk

def validate(char, entry_value):
    if char in 'VF ':
        print('entry value: {P}'.format(P = entry_value))
        return True
    else:
        print('invalid: {s}'.format(s = char))
        return False

root = tk.Tk()
vcmd = (root.register(validate), '%S', '%P')
entry = tk.Entry(root, validate = 'key', validatecommand = vcmd)
entry.pack()
entry.focus()

root.mainloop()

I don't have a documentation reference; I learned this here.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677