在Kivy文本输入窗口小部件中处理Tab / Enter(和其他击键)

时间:2012-08-20 12:09:36

标签: python kivy

我正在使用Kivy框架编写一个应用程序,我偶然发现了一个轻微但令人讨厌的问题:我不知道如何在文本字段中处理 Tab / Enter / Arrow 键以便按他们会派遣一个活动,例如。将焦点(跳转)切换到另一个 TextInput 或启动类似send_form()

的内容

有人可以对这个问题有所了解吗?

4 个答案:

答案 0 :(得分:24)

Kivy 1.9提供了在文本输入(see docs)上设置write_tab: False的功能,使Tab键可以专注于下一个可聚焦的小部件。

Kivy允许输入密钥通过设置multiline: Falseon_text_validate: root.foo()来分发事件。

因此,要创建具有所需Enter和Tab功能的文本输入窗口小部件,请执行以下操作:

TextInput:
    write_tab: False
    multiline: False
    on_text_validate: root.foo()

答案 1 :(得分:7)

刚刚发现这个老问题,并认为我会做出贡献。我还需要tab / enter才能转到下一个字段。我做了@tshirtman所建议的。这是我的自定义TextInput类:

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)

这允许您在实例化输入时传递next,或者在现有输入上调用set_next

9和13是tab和key的关键代码。

适合我。

答案 2 :(得分:3)

正如Daniel Kinsman在他的评论中所建议的那样,你可以继承TextInput,添加“previous”和“next”ObjectProperties以获得标签支持(使用对其他小部件的引用很容易在kv中设置),并以不同方式处理键盘事件。现在没有开箱即用的支持,但如果您想进行此类修改,请向我们发送功能请求,或者在freenode上的#kivy中进行讨论。

https://github.com/kivy/kivy/blob/master/kivy/uix/textinput.py#L1188

也许在小部件上添加这样的支持会更好,并添加一些焦点逻辑,因此tab / enter会对任何可激活的小部件产生影响,而某些小部件如滑块也会使用右/左/上/下键。 / p>

所以Kivy还有很多工作要做,如果你有兴趣帮助,你可以更快地实现它,我们会帮助你:)。

答案 3 :(得分:0)

[仅需注释,所以请在此处添加......

需要特别注意的是,只有当下一个字段由相同键盘布局管理时,键盘NEXT行为才能轻松起作用。但是,高级应用将具有:

  • 用户名(qwerty)
  • 密码(密码)
  • ID(数字) 等等

所以上面的方法真的行不通。

在kv文件中:

    MyTextInput:
        next: idTheNextFieldBelowThis

在您的MyTextInput类中:

    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