我正在尝试使输入文本仅接受浮点值。另外,输入的值必须介于两个值之间。
我创建了一个包含'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()
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)
一种合适的方法除了可以在范围内进行浮动之外,还可以对其进行过滤,为此我们创建了一个继承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()
您可以使用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()
输出:
我尝试了@eyllanesc的代码。它工作得很好,但是当我键入数字以外的其他字符时,出现此错误:ValueError: could not convert string to float: ''
。您能帮我解决这个问题吗?