Tab/Enter (and other keystrokes) handling in Kivy's TextInput widgets

前端 未结 4 1911
夕颜
夕颜 2021-02-05 13:53

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

相关标签:
4条回答
  • 2021-02-05 13:59

    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 :)

    0 讨论(0)
  • 2021-02-05 14:04

    [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:

    • username (qwerty)
    • password (password)
    • ID (numeric) etc

    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
    
    0 讨论(0)
  • 2021-02-05 14:07

    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()
    
    0 讨论(0)
  • 2021-02-05 14:20

    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.

    0 讨论(0)
提交回复
热议问题