Python Kivy-InputText上的限制值

Python Kivy-InputText上的限制值,python,kivy,kivy-language,Python,Kivy,Kivy Language,我试图创建一个只接受浮点值的输入文本。此外,输入的值必须介于两个值之间 我创建了一个包含“validate”方法的类。如果该值不在两个值之间,将显示一个弹出窗口 但我有个问题。该方法仅在用户点击“Enter”时调用。我尝试在文本更改时调用该方法,但这对用户来说很烦人,因为当用户输入数据时,弹出窗口总是出现 还有其他方法可以做这样的事情吗 Python文件: class BoundedInput(BoxLayout): value = NumericProperty() def

我试图创建一个只接受浮点值的输入文本。此外,输入的值必须介于两个值之间

我创建了一个包含“validate”方法的类。如果该值不在两个值之间,将显示一个弹出窗口

但我有个问题。该方法仅在用户点击“Enter”时调用。我尝试在文本更改时调用该方法,但这对用户来说很烦人,因为当用户输入数据时,弹出窗口总是出现

还有其他方法可以做这样的事情吗

Python文件:

class BoundedInput(BoxLayout):
    value = NumericProperty()

    def validate(self, min_value, max_value):
        status = min_value <= self.value <= max_value
        if not status:
            message = f'Value must be between {min_value} and {max_value}'
            popup = Popup(title='Warning', content=Label(text=message),
                            size_hint=(None, None), size=(300, 200))
            popup.open()
<NumericInput@TextInput>:
    input_filter: 'float'
    multiline: False

<BoundedInput>:
    orientation: 'horizontal'
    Label:
        text: 'Value'
    NumericInput:
        text: str(root.value)
        on_text_validate:
            root.value = float(self.text)
            root.validate(5, 100)
类边界输入(BoxLayout):
value=NumericProperty()
def验证(自身、最小值、最大值):

status=min_value一种合适的方法可以是过滤,除了将其浮动在范围内之外,我们还可以创建一个继承
TextInput
的类,并覆盖insert_text方法:

from kivy.app import App
from kivy.base import Builder
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput


Builder.load_string("""
<BoundedLayout>:
    orientation: 'horizontal'
    Label:
        text: 'Value'
    NumericInput:
        min_value : 5
        max_value : 100
        hint_text : 'Enter values between {} and {}'.format(self.min_value, self.max_value)
""")

class NumericInput(TextInput):
    min_value = NumericProperty()
    max_value = NumericProperty()
    def __init__(self, *args, **kwargs):
        TextInput.__init__(self, *args, **kwargs)
        self.input_filter = 'float'
        self.multiline = False

    def insert_text(self, string, from_undo=False):
        new_text = self.text + string
        if new_text != "":
            if self.min_value <= float(new_text) <= self.max_value:
                TextInput.insert_text(self, string, from_undo=from_undo)

class BoundedLayout(BoxLayout):
    pass

class MyApp(App):
    def build(self):
        return BoundedLayout()

if __name__ == '__main__':
    MyApp().run()
从kivy.app导入应用
从kivy.base导入生成器
从kivy.properties导入NumericProperty
从kivy.uix.boxlayout导入boxlayout
从kivy.uix.textinput导入textinput
生成器。加载\u字符串(“”)
:
方向:“水平”
标签:
文本:“值”
数字输入:
最小值:5
最大值:100
提示文字:'输入介于{}和{}之间的值。格式(self.min_值、self.max_值)
""")
类数值输入(文本输入):
最小值=数值属性()
最大值=数值属性()
定义初始化(self,*args,**kwargs):
TextInput.\uuuuu初始化(self,*args,**kwargs)
self.input_filter='float'
self.multiline=False
def insert_text(self,string,from_undo=False):
新建文本=self.text+字符串
如果是新文本!="":
如果self.min_值可以使用,只要输入错误,就可以挂起它。
您甚至可以编辑标签来判断错误。
或更改文本颜色(如果已验证或未验证)。
我举了一个例子,说明这两种方法都得到了实现

from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.bubble import Bubble
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import BooleanProperty

KV = """

<ValidateLabel>:
    size_hint: (None, None)
    size: (280, 60)
    Label:
        id: label
        text: "Must be a float"


<MyInput>:
    foreground_color: (0,1,0,1) if root.validated else (1,0,0,1)


FloatInput:

"""


class MyInput(TextInput):
    validated = BooleanProperty(False)


class FloatInput(FloatLayout):
    bubble_showed = True

    def __init__(self, **kwargs):
        super(FloatInput, self).__init__(**kwargs)
        self.input = MyInput()
        self.input.bind(text=self.validate)
        self.add_widget(self.input)
        self.bubble = ValidateLabel()
        self.add_widget(self.bubble)

    def validate(self, input, value, min_value=15., max_value=25.):
        self.bubble.ids.label.text = "Number must be between {} and {}".format(min_value, max_value)
        try:
            print(min_value, max_value)
            status = float(min_value) <= float(value) <= float(max_value)
        except Exception as e:
            status = False
            self.bubble.ids.label.text = "Input must be a number"

        if not status:
            if not self.bubble_showed:
                self.input.validated = False
                self.add_widget(self.bubble)
                self.bubble_showed = True
        else:
            print("bubble removed")
            self.input.validated = True
            self.remove_widget(self.bubble)
            self.bubble_showed = False


class ValidateLabel(Bubble):
    validated = False


class TestApp(App):

    def build(self):
        return Builder.load_string(KV)


TestApp().run()
从kivy.app导入应用
从kivy.uix.textinput导入textinput
从kivy.uix.bubble导入bubble
从kivy.lang导入生成器
从kivy.uix.floatlayout导入floatlayout
从kivy.properties导入布尔属性
KV=”“”
:
大小提示:(无,无)
尺寸:(280,60)
标签:
id:标签
文本:“必须是浮点型”
:
前景颜色:(0,1,0,1)如果root.else(1,0,0,1)
浮动输入:
"""
类MyInput(文本输入):
已验证=布尔属性(False)
类FloatInput(FloatLayout):
气泡显示为真
定义初始(自我,**kwargs):
超级(FloatInput,self)。\uuuuuu初始化(**kwargs)
self.input=MyInput()
self.input.bind(text=self.validate)
self.add_小部件(self.input)
self.bubble=ValidateLabel()
self.add_小部件(self.bubble)
def验证(自身、输入、值、最小值=15、最大值=25):
self.bubble.ids.label.text=“数字必须介于{}和{}之间”。格式(最小值、最大值)
尝试:
打印(最小值、最大值)

状态=浮动(最小值),这是一个很好的方法。唯一的问题是用户不知道为什么他们不能输入一些值。我在输入文本中添加了一个“提示文本”来通知用户最小值和最大值。谢谢@爱德华多:当然,这是对我的解决方案的补充。@Eduardo我已经添加了它,如果我的答案对你有帮助,你可以将它标记为正确的:DI发现了一个问题,我不能从一开始就输入“100”。我将研究如何解决它。如果我错了,请纠正我,但此验证不假设子字符串被追加吗?如果新文本插入到现有文本的中间,即3.90到39.90将检查3.909是否在范围内,这是一个很好的方法。适当地通知用户。我会试试看,我会回来发表评论。@Eduardo是的,在我看来,至少有两种方式是合得来的。绿色表示没问题,不需要气泡。祝你好运