QValidator验证器对象
- 描述
- 用于验证用户输入数据的合法性
- QValidator是一个抽象类,不能直接实例化创建对象
- 直接使用实例化创建对象(
validator = QValidator()
)会报错 - 需要子类化该类(自定义类继承自该类)
- 自定义子类化
class MyValidator(QValidator): def ...
- 系统提供子类
QIntValidator(bottom, top, parent) # 限制整型数据范围 QDoubleValidator # 浮点类型数据限制范围(经测试无效,需要手动实现) QRegExpValidator # 通过正则表达式限定
- 自定义子类化
- 自定义类中需要重写 validate 和 fixup 两个方法,来对文本框内容进行验证判断并返回判定结果
- 系统提供的子类,并没有修复功能,需要重写 fixup 方法
- 执行过程
- 如果一个输入框设置了验证器:用户在文本框中输入内容时
- ① 首先会将用户输入的内容传递给验证器进行验证:
validate(self, input_text, pos)
- ② 验证器根据接收到的输入内容(input_text)和光标位置(pos),进行判断。根据判断返回不同的结果
return (QValidator.Acceptable, input_text, pos) # 验证通过 return (QValidator.Intermediate, input_text, pos) # 暂不作判定是否通过验证 return (QValidator.Invalid, input_text, pos) # 验证不通过 * 返回的内容input_text不会显示在文本框中
- ③ 如果输入框结束输入后, 上述的验证状态为:暂不作判定是否通过验证(返回结果是
QValidator.Intermediate
), 则会调用修复方法:fixup(self, input_text)
fixup(self, input_text) return 修正后文本
- ④ 通过fixup()方法后,会将修正后文本写入文本框,此时文本框内容发生改变,又会调用
validate()
方法进行验证 - ⑤ 如果通过fixup()方法修正后的文本,依然并非有效(不满足条件),那么程序也不会再调用fixup()方法进行修正了,而且只判断是否有效,并不会将修正后的文本写入到文本框(文本框显示修正之前的文本)
- ⑥ 如果通过fixup()方法修正后的文本,依然有效,程序将返回
QValidator.Acceptable
,并将文本框的内容修改为修正后的文本 - 注意:
validate()
文本框设置了验证后,当内容发生改变时调用该方法fixup()
文本框设置了验证后,当文本框丢失焦点时,并且validate方法返回的是QQValidator.Intermediate
状态时会调用该方法。validate()
方法返回的是QValidator.Invalid
时,文本框会限制输入validate()
只有当返回值为QValidator.Acceptable
时,才会将input_text
写入到文本框中
- ① 首先会将用户输入的内容传递给验证器进行验证:
系统提供子类
QIntValidator(bottom, top, parent) # 限制整型数据范围
QDoubleValidator # 浮点类型数据限制范围(经测试无效,需要手动实现)
QRegExpValidator # 通过正则表达式限定
- QIntValidator(最小值, 最大值, 父类)
- 限制整形数据范围
- 该对象只实现了 validate() 方法,对输入的内容进行了判定,但是对于处于
QValidator.Intermediate
状态的内容没有进行修复 fixup()
方法需要通过自定义类继承自QIntValidator来进行重写- 相对于直接子类化QValidator来说,可以减少重写
validate()
方法 - 注意:通过测试,三个系统提供的子类都没办法进行限制
- 演示代码
- 示例1:QValidator对象执行过程初体验
from PyQt5.Qt import * import sys class MyValidator(QValidator): """子类化QValidator类""" def validate(self, a0: str, a1: int): """ 文本框设置了验证后,当内容发生改变时调用该方法 :param a0: 文本框内容 :param a1: 光标位置 :return: 返回验证状态 QValidator.Acceptable:验证通过 QValidator.Intermediate:暂不验证,文本框失去焦点时调用fixup()方法进行验证 QValidator.Invalid:验证不通过 """ try: if 1 <= int(a0) <= 17: print('暂时不处理', a0) return (QValidator.Intermediate, '19', a1) elif 18 <= int(a0) <= 120: print('validator中满足条件', a0) return (QValidator.Acceptable, '20', a1) else: print('validator中超出范围', a0) return (QValidator.Invalid, '21', a1) except: print('validator中转换报错', a0) return (QValidator.Invalid, '22', a1) def fixup(self, a0: str) -> str: """ 当文本框失去焦点,并且validate返回的是 QValidator.Intermediate 时调用 :param a0: 文本框内容 :return: 返回要显示在文本框里面的内容 """ try: if 18 <= int(a0) <= 120: print('fixup中满足条件', a0) return a0 else: print('fixup中超出范围', a0) return a0 except: print('fixup中转换报错', a0) return a0 class Windows(QWidget): def __init__(self): super().__init__() self.setWindowTitle('QValidator验证器使用') self.resize(980, 500) self.widget_list() def widget_list(self): self.add_widget() def add_widget(self): le_1 = QLineEdit(self) le_2 = QLineEdit(self) le_1.move(100, 100) le_2.move(100, 150) le_1.setPlaceholderText('请输入数字18~120') validate = MyValidator() le_1.setValidator(validate) if __name__ == '__main__': app = QApplication(sys.argv) window = Windows() window.show() sys.exit(app.exec_())
- 示例2:QValidator对象执行过程跟踪
from PyQt5.Qt import * import sys class MyValidator(QValidator): i = 6 def validate(self, a0: str, a1: int): s = str(MyValidator.i) try: a = int(a0) if 1 <= a <= 9: print('Validator中暂时不判断', a0, s) # a0 = str(a + 1) return (QValidator.Intermediate, a0, a1) elif 10 <= a <= 99: print('Validator中条件满足', a0, s) # a0 = str(a + 1) return (QValidator.Acceptable, a0, a1) else: print('Validator中判断,值太大', a0, s) # a0 = str(a - 1) return (QValidator.Invalid, a0, a1) except: print('数据类型错误!') return (QValidator.Invalid, a0, a1) def fixup(self, a0: str) -> str: MyValidator.i += 100 s = str(MyValidator.i) print('fixup进行修正', a0, s) return s class Windows(QWidget): def __init__(self): super().__init__() self.setWindowTitle('QValidator-test') self.resize(980, 500) self.widget_list() def widget_list(self): self.add_widget() def add_widget(self): le1 = QLineEdit(self) le2 = QLineEdit(self) le1.move(100, 100) le2.move(100, 200) validator = MyValidator() le1.setValidator(validator) if __name__ == '__main__': app = QApplication(sys.argv) window = Windows() window.show() sys.exit(app.exec_())