【问题标题】:Tab/Enter (and other keystrokes) handling in Kivy's TextInput widgetsKivy 的 TextInput 小部件中的 Tab/Enter(和其他击键)处理
【发布时间】:2012-08-15 18:24:01
【问题描述】:

我正在使用 Kivy 框架编写一个应用程序,我偶然发现了一个小而烦人的问题:我不知道如何处理文本字段中的 Tab/Enter/Arrow 键,以便按下任一其中会派发一个事件,例如。将焦点(跳转)到另一个 TextInput 或启动类似send_form()

谁能解释一下这个问题?

【问题讨论】:

  • 我认为现在 Kivy 中并没有很多支持这种东西,它们似乎主要是针对触摸的。您可以提交功能请求,或者考虑自己修改 kivy 的 TextInput 类; start here,见第 1266 行(elif key == 9: # tab)。也许在那里触发你自己的自定义事件?

标签: python kivy


【解决方案1】:

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

Kivy 允许 Enter 键通过设置 multiline: Falseon_text_validate: root.foo() 来调度事件。

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

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

【讨论】:

  • 谢谢,尽管它不适用于 Android(如 Kivy==1.10.0)。
  • 这帮助很大!谢谢!对于其他想知道 kivymd 的文本输入是否继承自 kivy TextInput 的人:答案是肯定的。
  • 谢谢,它还会使“shift+tab”向相反方向移动,即以前的可聚焦小部件吗?我尝试过,但只为前进方向而努力。
【解决方案2】:

刚刚发现了这个老问题,并认为我会做出贡献。我还需要制表符/输入才能转到下一个字段。我按照@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 和 enter 的键码。

很适合我。

【讨论】:

  • 哦,_keyboard_on_key_down 方法,正是我需要的!谢谢!
  • 所以我有一个带有调用的 TextInput 实例:on_text_validate: root.change_context()。我应该如何将它(在我的 kv 文件中)更改为 TabTextInput,以便我的 textinput 字段以多行模式运行?
【解决方案3】:

正如 Daniel Kinsman 在他的评论中所建议的,您可以将 TextInput 子类化,添加“上一个”和“下一个”ObjectProperties 以支持选项卡(使用对其他小部件的引用在 kv 中轻松设置),并以不同的方式处理键盘事件。目前还没有开箱即用的支持,但是如果您想进行此类修改,请向我们发送功能请求或在 freenode 上的#kivy 中讨论它。

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

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

所以在 Kivy 中还有很多事情要做,如果您有兴趣提供帮助,您真的可以更快地实现它,我们会帮助您:)

【讨论】:

  • 我确实需要键盘支持,即在点击“F1”或“”或“Ctrl+T”时激活(单击)小部件,在 Spinner 等选项之间使用箭头移动。这个将提高“普通”PC 的可用性。我会尽力帮助:)
  • @tshirtman,与此主题类似,在 Kivy 的文档中`on_text_validate Fired only in multiline=False mode, when the user hits 'enter'. This will also unfocus the textinput.。点击回车键后如何保持焦点。
【解决方案4】:

[点数不足以评论,所以在这里添加...]

请务必注意,只有在下一个字段由 same 键盘布局管理时,键盘 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

【讨论】:

  • 这个问题已经 7 岁了。还够吗?
  • 是的,绝对的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-21
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
相关资源
最近更新 更多