假设我有一个包含2个IntFields的表单。如何根据IntField A中的输入来验证IntField B? 例如如果A == 1,B只能在0-30之间;如果A == 2,则B只能在0-50之间;否则B可以是其他任何数字
从我能用谷歌搜索的所有内容中,我只能找到仅验证该字段而无法链接到另一个字段的IntValidator。我找不到能说明如何在IntValidator中更新最小值/最大值的示例,也没有任何示例可以获取另一个字段的值以使验证可以根据另一个字段中的值更改而改变的任何自定义Validator ... < / p>
enamldef IntFieldsWindow( Window ):
Container:
Form:
padding=0
Label:
text = 'Field A'
IntField: fld_a:
value = 0
Label:
text = 'Field B'
IntField: fld_b:
value = 0
经过一些测试,实际上可以将fld_a传递给自定义验证器,然后在validate函数中获取fld_a.value,最后将自定义验证器设置为fld_b。不确定是否是进行这种验证的方法。
答案 0 :(得分:0)
一种方法是将数据分解为模型,并使用观察者(当任一成员发生更改时调用该观察者)来验证成员。
然后将IntField
绑定到模型值(使用<<
),并使用捕获并报告验证错误的通知处理程序(::
)来更新模型值。
例如:
from atom.api import Atom, Int, observe
from enaml.stdlib.fields import IntField
from enaml.widgets.api import Window, Container, Label, Form
class Model(Atom):
a = Int()
b = Int()
@observe('a', 'b')
def _validate(self, change):
# When a or b is changed validate the model state
a, b = self.a, self.b
if a == 1:
if b < 0 or b > 30:
raise ValueError("B is out of range")
elif a == 2:
if b < 0 or b > 50:
raise ValueError("B is out of range")
enamldef Main(Window):
attr model = Model()
Container:
Form:
padding=0
Label:
text = 'Field A'
IntField: fld_a:
value << model.a
value ::
error.text = ''
try:
model.a = change['value']
except ValueError as e:
error.text = str(e)
Label:
text = 'Field B'
IntField: fld_b:
value << model.b
value ::
error.text = ''
try:
model.b = change['value']
except ValueError as e:
error.text = str(e)
Label:
text << 'A:{} B:{}'.format(model.a, model.b)
Label: error:
pass
请注意,输出模型值的标签永远不会处于无效状态!模型上的验证器将确保这种情况永远不会发生。