我正在尝试创建一个只接受浮点值的输入文本。此外,输入的值必须介于两个值之间。
我创建了一个包含'validate'方法的类。如果值不在两个值之间,则显示Popup。
但我有一个问题。只有在用户点击“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()
Kv档案:
<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)
答案 0 :(得分:3)
一个合适的方法可以是过滤,除了浮动它也在它的范围内我们创建一个继承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()
答案 1 :(得分:2)
您可以使用Bubble,并在输入错误时将其挂起
你甚至可以编辑标签以告诉错误。
或者,如果验证了,则更改文本颜色
我做了两个实例的例子。
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()
输出: