设为首页 加入收藏

TOP

QLineEdit拾遗:数据的过滤、验证和补全(一)
2019-03-15 00:08:55 】 浏览:178
Tags:QLineEdit 拾遗 数据 过滤 验证

QLineEdit是使用频率最高的控件之一,当我们想获取用户输入时自然而然得会用到它。

通常我们会将QLineEdit的信号或其他控件的信号绑定至槽函数,然后获取并处理编辑器内的数据。你会觉得我们拿到的是第一手的“热乎着”的数据,所以理所当然地将过滤和验证逻辑都加入槽函数中,然而事实并非如此。那么数据究竟通过了哪些流程最终才经由信号被我们获取呢?

或者你希望QLineEdit能拥有自动补全或是输入联想的功能,这又如何实现呢?

如果你对上面的问题毫无头绪,那么本文就是为你量身打造的,请继续往下阅读吧!

本文索引

引论

这一节将带你概览QLineEdit对数据的处理,并以一个示例引出后续章节的内容。你可以先在此处找到一些粗浅的回答,后续则会有详细的解释。

如果要简单的回答第一问,那么在我们获取到text内容前需要经过两个步骤:

它们分别由inputMaskQValidator实现,前者负责过滤用户的输入,后者则用于过滤后的信息的验证。

inputMaskvalidator的表现很相似,有时它们的功能还会有一些重合,那么它们是否能取代彼此呢?答案是否定的,看起来像鸭子的鸟有时候其实不是和鸭子没关系,后面我们仔细说明。

现在轮到回答第二个问题了。要实现补全和自动联想,你只需要将一个设置好的QCompleter对象传递给QLineEdit。是不是够简单?大部分时间也确实如此,然而“设置好的”这一形容词的很抽象的概念,所以有的时候你可能要失望了,不过别担心,后面我们也会详细介绍它的使用。

两问回答完毕,现在该来看看本文的示例了。这次我们将自己实现一个DateEdit(我知道有现成的QDateEdit,不过这里请允许我为了实践所学而造一个粗糙的轮子),并根据用户输入的日期计算当天是周几,效果如下:

实现CustomDateEdit

在本节中我们将逐步实现CustomDateEdit,并详细介绍引论中提到的概念。

按照流程图的顺序,我们首先要讲解的便是输入数据的过滤——inputMask的功能。

过滤用户输入——inputMask

在具体介绍一个能控制显示效果的特性前,我习惯于先描述其大致功能和具体的显示效果。

inputMask的功能:它是一串特定的规则,所有不符合规则的用户输入都会被丢弃,用户不管是从信号还是text槽都只能获取符合mask要求的输入数据,当然这个“用户”包括我们后面要介绍的QValidator及其派生类。

inputMask的显示效果:你只能输入合法的字符,输入非法字符是输入内容无法显示,光标停留在原处;如果你设置了mask的填充字符,则这些字符会显示在edit中,当输入合法字符时将覆盖它们,mask中的保留字符同样显示在edit中,但输入时会被跳过不可覆盖(类似占位符),引论中的效果图就是很好的例子。

inputMask就是一串由特殊字符组成的规则,通过规则给定的格式来控制文本的输入,具体的规则见下表:

特殊字符 对应规则
A 必须输入的ascii字母,包括A-Z,a-z
a A一样,但是可选,也就是不输入这个字符也可以,占位符将保留
N 必须输入的ascii字母和数字,包括A-Z,a-z,0-9
n N一样,但是可选
X 必须输入的任意字符
x X一样,但是可选
9 必填的ascii的数字字符,包括0-9
0 9一样,但是可选
D 必填的数字,包括1-9
d D一样,但可选
# 可选的数字或者加减号
H 必填的16进制的数字,包括A-F, a-f, 0-9
h H一样,但可选
B 必填的二进制数字,包括0和1
b B一样,但可选
> 所有在这个特殊字符之后的字符转换为大写
< 所有在这个特殊字符之后的字符转换为小写
! 关闭前面的大小写转换
[ ] { } 保留的特殊字符
\ 将特殊字符转义为普通字符

inputMask的格式为:([特殊字符]|[普通字符])*;占位符,分号后跟的是占位符,用于填充特殊字符留下的空位,默认为空格。下面看些例子:

  1. 000,000.00;_:用于输入一个最大6位,有两位小数的值,用_填充空位,edit会显示出类似___,___.__的效果
  2. >AAAA-AAAA!-AAAA-AAAA:用于输入一个由连字符分割的字母数字组成的uuid或license key,且前八个字母会被转换为大写,在edit中显示为- - -
  3. 9999年09月09日:用于输入年月日的时间格式,可以输入2019年03月14日2019年3月14日,显示效果在引论的效果图中。
  4. 空字符串:表示没有任何输入限制

你可以通过setInputMask设置mask,或inputMask获取当前的mask。

通过上面的说明和例子你应该已经学会了inputMask的使用,现在可以看看它与validator的区别了:

  1. inputMask在用户进行输入时进行过滤,并且只存在符合规则和不符合两种状态,validator通常拥有第三种状态
  2. inputMask只能过滤较为固定的格式,并且对于输入的最大长度产生限制,validator则要灵活的多

最主要的区别是这两点。上一节提到inputMask不能替代validator,现在我们揭晓原因:inputMask只能保证输入数据的格式,但并不保证数据有意义,比如例子3中我们可以在月份上输入20,但明显日期中没有20月,而这种错误是inputMask无法处理的,这就是为什么我们说有时候一只看起来像鸭子的鸟也许和鸭子没有半点关系的原因。

因此想要获得正确的数据,我们还需要验证器来帮忙。

数据验证——QValidator

现在该验证我们的输入了。因为有了inputMask的帮助,现在我们只需要验证数据本身是否正确而不用操心它的格式了,真是谢天谢地。

等等,这么说好像不太对,validator拿到的数据里居然还保留着mask的占位符?你没看错,这不是bug,能在edit里显示出来的数据那么一定能被获得,mask本身的占位符是能通过过滤的,所以它会原封不动地传给validator,只有用户输入合法的数据后这些占位符才会被覆盖。所以在写自己的验证器的时候要小心了——我们需要先删除所有的占位符,因为它们不是数据的一部分!

下面我们来看看validator的功能和显示效果。

功能:验证数据是否合法,不合法会被丢弃,同时还要识别出数据是否输入完成,这就是validator返回的第三种状态。

显示效果:和inputMask一样。如果数据未输入完则保留在edit中。

大致概览后我们可以深入了解一下QValidator了,所有的验证器都是它的派生类。

QValidator本身是一个纯虚基类,派生类需要实现QValidator::State QValidator::validate(QString &input, int &pos

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇django-3-模板变量,过滤器,金泰文.. 下一篇python函数学习1

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目