【问题标题】:Move cursor to final position of string in a MDTextField将光标移动到 MDTextField 中字符串的最终位置
【发布时间】:2021-01-08 00:51:30
【问题描述】:

我正在尝试为我正在使用 KivyMD 开发的应用程序上的 MDTextField 提供日期格式。此类字段的格式为'dd/mm/yyyy'。

我想要做的是,一旦写入前 2 个数字,将自动写入“/”,光标将跳转到“/”右侧的最后一个位置(例如“21/”) .同理,在第一个'/'后面写入其他2个数字后,将写入第二个'/',光标将再次移动到末尾(例如'21/09/')。

我设法使两个“/”都出现了,但是,我无法将光标放在所需的位置。我的代码如下:

def apply_date_format(self):
    # delete '/' if len is equal or less than 2 and final character is /  
    if len(self.ids.viajeInicio.text) =< 2 and (self.ids.viajeInicio.text).endswith('/'):
        self.ids.viajeInicio.text = (self.ids.viajeInicio.text[:-1])
    # first '/'
    elif len(self.ids.viajeInicio.text) == 2 and (self.ids.viajeInicio.text).isnumeric():
        self.ids.viajeInicio.text= self.ids.viajeInicio.text + "/"
    # second '/'
    elif len(self.ids.viajeInicio.text) == 5 and (self.ids.viajeInicio.text[3:5]).isnumeric():
        self.ids.viajeInicio.text= self.ids.viajeInicio.text + "/"
    # delete last '/' if len is <= 5 and last character is '/'
    elif len(self.ids.viajeInicio.text) > 3 and len(self.ids.viajeInicio.text) <= 5 \
             and (self.ids.viajeInicio.text).endswith('/'):
        self.ids.viajeInicio.text = (self.ids.viajeInicio.text[:-1])

MDTextField 的 ID 为 viajeInicio,并且函数 apply_date_format 在 on_text 事件上被调用。代码如下:

MDTextField:
    id: viajeInicio
    hint_text: 'Ingresar Fecha de Inicio del Viaje'
    pos_hint: {"x":0, "top":1}
    helper_text: 'Formato de fecha: dd/mm/aaaa'
    helper_text_mode: 'on_focus'
    required: True
    on_text:
        root.apply_date_format()

如何在写入“/”后将光标位置移动到字符串的末尾。此外,有没有更好的方法来完成所需的任务?

提前非常感谢

【问题讨论】:

    标签: python kivy kivy-language cursor-position kivymd


    【解决方案1】:

    我认为扩展MDTextField 类并覆盖它的insert_text() 方法更简单。像这样的:

    class DateMDTextField(MDTextField):
        def insert_text(self, the_text, from_undo=False):
            if the_text == '/':
                # do not allow typed in '/'
                return
            cc, cr = self.cursor
            cur_text = self._lines[cr] + the_text  # existing text plus the to be inserted the_text
            cur_len = len(cur_text)
    
            # new_text will be inserted. The default is to just use the_text
            new_text = the_text
    
            # delete '/' if len is equal or less than 2 and final character is /
            if cur_len <= 2 and cur_text.endswith('/'):
                new_text = new_text[:-1]
            # first '/'
            elif cur_len == 2 and cur_text.isnumeric():
                new_text += '/'
            # second '/'
            elif cur_len == 5 and cur_text[3:5].isnumeric():
                new_text += '/'
            # delete last '/' if len is <= 5 and last character is '/'
            elif cur_len > 3 and cur_len <= 5 and cur_text.endswith('/'):
                new_text = new_text[:-1]
            # do not allow extra characters
            elif cur_len > 10:
                return
    
            # call the insert_text() of the MDTextField with the possibly modified text
            super(DateMDTextField, self).insert_text(new_text, from_undo=from_undo)
    

    上面的代码使用了你的逻辑(有几个小的补充),因为它最终调用了MDTextFieldinsert_text(),所以所有的光标移动都是为你处理的。

    所以你可以替换:

    MDTextField:
        id: viajeInicio
        hint_text: 'Ingresar Fecha de Inicio del Viaje'
        pos_hint: {"x":0, "top":1}
        helper_text: 'Formato de fecha: dd/mm/aaaa'
        helper_text_mode: 'on_focus'
        required: True
        on_text:
            root.apply_date_format()
    

    与:

    DateMDTextField:
        id: viajeInicio
        hint_text: 'Ingresar Fecha de Inicio del Viaje'
        pos_hint: {"x":0, "top":1}
        helper_text: 'Formato de fecha: dd/mm/aaaa'
        helper_text_mode: 'on_focus'
        required: True
    

    在你的'kv'中。您不需要显式调用insert_text() 方法,因为它由基类TextInput 自动调用。而且您也不需要on_text 条目。

    您不再需要apply_date_format() 方法。

    【讨论】:

    • 非常感谢约翰的回复。我还有一个问题要问你。如何从我的 KV 文件中调用这个类?在我之前的尝试中,我的函数在类中引用了特定的所需屏幕。所以我使用了 root.my_function()。如何在 Kivy 上调用其他类的函数?提前非常感谢。
    • 我尝试使用以下代码:code def apply_date_format(self): DateMDTextField.insert_text(self.ids.viajeFinal, self.ids.viajeFinal.text) code 我能够运行该程序,但它有我不想要的结果。如果我只输入 1 个数字(例如“2”),TextField 会自动更新为“2/22/2”
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    相关资源
    最近更新 更多