I\'m writing an app using Kivy framework and I stumbled upon a minor but annoying problem: I don\'t know how to handle Tab/Enter/Arrow keys in text fields so that press
As suggested by Daniel Kinsman in his comment, you could subclass TextInput, add "previous" and "next" ObjectProperties for tab support (easy to set in kv using references to other widgets), and handle the keyboard events differently. There is no out of the box support for this right now, but if you want to work on such modification drop us a feature-request or comme discuss it in #kivy on freenode.
https://github.com/kivy/kivy/blob/master/kivy/uix/textinput.py#L1188
Maybe it would be even better to add such support on widget, and add some focus logic, so tab/enter have effects on any activable widget, and some widgets like slider use right/left/up/down keys too.
So there is still a lot to do in Kivy about that, and if you are interested in helping, you can really make it happen faster, we'll help you :)
[Insufficient points to just comment, so adding this here...]
It's crucial to note that the keyboard NEXT behavior only works easily if the next field is managed by the same keyboard layout. However, an advanced app will have:
So the approaches above really doesn't work out.
In the kv file:
MyTextInput:
next: idTheNextFieldBelowThis
In your MyTextInput class:
def insert_text(self, value, from_undo=False):
#
# Unfortunately the TextInput write_tab behavior only works if the next field is the same exact keyboard
# type.
#
if not value[-1:] == ' ':
return super(MyTextInput, self).insert_text(value, from_undo=from_undo)
r = super(MyTextInput, self).insert_text(value[:-1], from_undo=from_undo)
if self.next is not None:
self.next.focus = True
return r
Kivy 1.9 provides the ability to set write_tab: False
on text inputs (see docs), causing the tab key to focus on the next focusable widget.
Kivy allows the Enter key to dispatch events by setting multiline: False
and on_text_validate: root.foo()
.
So, to create a text input widget that has the desired Enter and Tab functionality, do as follows:
TextInput:
write_tab: False
multiline: False
on_text_validate: root.foo()
Just found this old question and figured I would contribute. I also needed tab / enter to go to the next field. I did what @tshirtman suggested. This is my custom TextInput
class:
from kivy.uix.textinput import TextInput
class TabTextInput(TextInput):
def __init__(self, *args, **kwargs):
self.next = kwargs.pop('next', None)
super(TabTextInput, self).__init__(*args, **kwargs)
def set_next(self, next):
self.next = next
def _keyboard_on_key_down(self, window, keycode, text, modifiers):
key, key_str = keycode
if key in (9, 13) and self.next is not None:
self.next.focus = True
self.next.select_all()
else:
super(TabTextInput, self)._keyboard_on_key_down(window, keycode, text, modifiers)
This allows you to pass next
when you instantiate the input, or alternatively call set_next
on an existing input.
9 and 13 are the key codes for tab and enter.
Works well for me.