038.PyQt5_补QValidator_验证器对象

QValidator验证器对象

  • 描述
    • 用于验证用户输入数据的合法性
    • QValidator是一个抽象类,不能直接实例化创建对象
    • 直接使用实例化创建对象( validator = QValidator() )会报错
    • 038.PyQt5_补QValidator_验证器对象_第1张图片

    • 需要子类化该类(自定义类继承自该类)
      • 自定义子类化
        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_())

     

你可能感兴趣的:(PyQt5,python,qt5,pyqt,qt,开发语言)