You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy中TextInput自动补冒号后光标位置调整求助

解决Kivy TextInput自动添加冒号后光标位置异常问题

我正在开发一个时间输入的TextInput组件,需求是:

  • 输入前两位数字后自动添加冒号(如输入11变为11:)
  • 输入接下来两位数字后继续添加冒号(如输入22变为11:22:)

但目前遇到问题:自动添加冒号后,光标会停留在冒号前方,希望光标能自动移动到冒号后方。尝试过instance.cursor = (len(instance.text), 0)但没生效,需要正确的光标刷新方式。

修复后的代码

from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.clock import Clock

Builder.load_string("""
<KTextInput>:
    hint_text: "00:00:00"
    input_filter: 'int'  # 内置过滤,只允许输入数字
""")

class KTextInput(TextInput):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.bind(text=self._on_text)

    def _on_text(self, instance, text):
        # 重构格式化逻辑:先清掉所有冒号,再按两位一组重新拼接
        clean_text = text.replace(":", "")
        formatted_segments = []
        # 按两位分割数字,最多保留三组(对应HH:MM:SS)
        for i in range(0, len(clean_text), 2):
            formatted_segments.append(clean_text[i:i+2])
        final_text = ":".join(formatted_segments[:3])
        
        if final_text != text:
            self.text = final_text
            # 延迟设置光标到末尾,确保文本更新完成后生效
            Clock.schedule_once(lambda dt: setattr(self, 'cursor', (len(self.text), 0)))

if __name__ == "__main__":
    from kivy.app import App
    class TestApp(App):
        def build(self):
            return KTextInput()
    
    TestApp().run()

关键改动说明

  1. 用内置输入过滤替代自定义判断:直接设置input_filter: 'int',无需自己处理非数字输入,逻辑更简洁可靠。
  2. 重构格式化逻辑:先清除所有冒号再重新分组拼接,避免原逻辑中重复触发文本绑定的问题,同时支持删除操作后自动重新格式化。
  3. 延迟设置光标:通过Clock.schedule_once延迟调整光标位置——因为直接修改self.text后,Kivy会自动重置光标,延迟执行能确保文本更新完成后再将光标移到末尾。
  4. 移除冗余键盘绑定:不再需要监听键盘事件记录输入字符,简化代码结构。

额外优化点

这个方案还优化了整体输入体验:删除中间数字后,文本会自动重新整理成HH:MM:SS格式,同时限制最多输入6位数字,符合时间输入的合理长度。

内容的提问来源于stack exchange,提问作者Ten Kho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:45:35