This might be a simple answer.
I have a text widget which i want to bind any alphanumeric keyboard key (a-zA-Z0-9_ and rest of regular keys) to a specific method, and Ctrl+F to another method.
Using widget.bind("<Key>", method)
will create the following:
method
twice, one for Ctrl (event.keysym = Control_L, event.char = None
) and second for F (event.keysym = f, event.char = <invalid>
)method
(event.keysym = f, event.char = f
)Is there a way to distinguish between the two scenarios?
You can bind <Control-f>
and <f>
(and the same with other keys).
import tkinter as tk
# --- functions ---
def key_f(event):
print('key: f')
def key_shift_f(event):
print('key: Shift + f')
def key_control_f(event):
print('key: Control + f')
def key_control_shift_f(event):
print('key: Control+Shift + f')
# --- main ---
root = tk.Tk()
#root.bind("<f>", key_f) # it works too
#root.bind("<F>", key_shift_f) # it works too
root.bind("f", key_f)
root.bind("F", key_shift_f)
root.bind("<Control-f>", key_control_f)
root.bind("<Control-F>", key_control_shift_f)
root.mainloop()
Or you can use event.state & 4
to recognize key with Control
.
You need bit-wise &
because it keeps information about other special keys
(see Masks/Modifier
on http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/event-handlers.html)
import tkinter as tk
# --- functions ---
def method(event):
print('-----')
print('[DEBUG] event.char :', event.char)
print('[DEBUG] event.keysym:', event.keysym)
print('[DEBUG] event.state :', event.state, '=', bin(event.state))
if event.char: # skip Control_L, etc.
# if you need `& 5` then it has to be before `& 4`
if event.state & 5 == 5: # it needs `== 5` because `& 5` can give results `5`, `4` or `1` which give `True` or `0` which gives `False`
print('method: Control+Shift +', event.keysym)
elif event.state & 4: # it doesn't need `== 4` because `& 4` can give only results `4` or `0`
print('method: Control +', event.keysym)
elif event.state & 1: # it doesn't need `== 1` because `& 1` can give only results `1` or `0`
print('method: Shift +', event.keysym)
else:
print('method:', event.keysym)
# --- main ---
root = tk.Tk()
root.bind("<Key>", method)
root.mainloop()