Kivy:TextInputs是否有“BoundedString”属性可用?

3

有没有一种方法可以使TextInput接收有界字符串值(即最大长度为x的字符串)?我尝试调查如何混合使用AliasProperty以模拟BoundedNumericProperty,但找不到任何属性类方法。


为什么不只重载insert_text来限制TextInput中输入的文本呢? - qua-non
3个回答

7
在调用on_text时,文本已经在文本输入框中更改。您需要覆盖insert_text以在将文本插入TextInput之前捕获文本,因此在更新text属性之前限制TextInput的输入。
请不要绑定/请求键盘,因为TextInput会为您执行此操作,而且在TextInput获得焦点后,您的处理程序将停止工作(TextInput将请求键盘,在单个键盘环境中,您的处理程序将停止工作)。
以下是一个示例代码,覆盖insert_text以仅限制数字输入的文本输入。
class NumericInput(TextInput):

    def insert_text(self, substring, from_undo=False):
        if not from_undo:
            try:
                int(substring)
            except ValueError:
                return
        super(NumericInput, self).insert_text(substring, from_undo)

如果要限制文本的长度,可以采取以下方法:

class CustomInput(TextInput):

    max_chars = NumericProperty(10)

    def insert_text(self, substring, from_undo=False):
        if not from_undo and (len(self.text)+len(substring) > self.max_chars):
            return
        super(CustomInput, self).insert_text(substring, from_undo)

得停止试图重新发明轮子。谢谢! - Noob Saibot

3
我认为on_text事件会在每次修改文本时触发。因此,您可以重写该方法:
def on_text(self, instance, value):
    print('The widget', instance, 'have:', value)

    # validate here!!!

    # you might also want to call the parent.
    #super(ClassName, self).on_text(instance, value)

或者绑定它:

def my_callback(instance, value):
    print('The widget', instance, 'have:', value)
    #validate here

textinput = TextInput()
textinput.bind(text=my_callback)

小心无限递归。如果你在on_textmy_callback内部修改文本变量,可能会触发事件。我不确定是否会触发,但我认为会,因此在修改变量之前需要使用验证标志。

您还可以使用on_focus来检查何时失去TextInput的焦点:

def on_focus(instance, value):
    if value:
        print('User focused', instance)
    else:
        print('User defocused', instance)

textinput = TextInput()
textinput.bind(focus=on_focus)

最后,您还可以绑定键盘,以便在TextInput之前保证访问。我真的不知道执行顺序,但如果使用on_text,您可能会在字母出现在屏幕上后删除它,这可能是不可取的。

我认为实现自己的BoundedStringProperty将是相当大的工作,以实现您想要的功能。这里是BoundedNumericProperty的代码

此外,您不应该尝试使用AliasProperty,因为您已经拥有了触发上述on_text事件的StringProperty


1

以上代码存在一个简单的问题。您需要使用NumericProperty.defaultvalue才能使用该代码(在长度比较中)。以下是一个简单的子类,可用于创建适合任何大小的类。

class CustomInput(TextInput):

def  __init__(self , **kwargs):
    if "max_chars" in kwargs:
        self.max_chars = NumericProperty(int(kwargs["max_chars"]))
    super(CustomInput , self ).__init__(**kwargs)

def insert_text( self , substring , from_undo = False ):
    if not from_undo and ( len( self.text ) + len( substring ) > self.max_chars.defaultvalue ):
        return
    super( CustomInput , self).insert_text( substring , from_undo)

我将max_chars作为关键字参数传递给init。 如果我使用int而不是NumericProperty来表示max_chars,则这将起作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接