-
Notifications
You must be signed in to change notification settings - Fork 7
/
ch05-02.htm
1745 lines (1185 loc) · 113 KB
/
ch05-02.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>ch05-02</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="thumbnailviewer.css" type="text/css">
<script src="thumbnailviewer.js" type="text/javascript">
/***********************************************
* Image Thumbnail Viewer Script- © Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
</script> </head>
<body>
<div class="os1">5.2 单行编辑控件 </div>
<br>
在图形界面程序中,有很多的输入控件,其中以文本编辑控件最为常用,可以接收用户输入的各种文本,比如登录界面常见的用户名、密码,网络连接使用的 IP 和
端口等等,本节先大致介绍一下 Qt
里面的文本编辑和浏览控件,然后详细讲解单行编辑控件的用途,通过三个例子示范单行编辑控件的使用。对于多行丰富内容的文本编辑控件,留在下一节讲解。<br>
<br>
<div class="os2">5.2.1 文本编辑控件概述</div>
<br>
从 Qt 设计师界面可以看到常用的 Qt 文本编辑和浏览控件,包括四个:<br>
<center><img src="images/ch05/ch05-02-01.png" alt="edit"></center>
其中单行编辑控件 QLineEdit 和 普通文本编辑控件 QPlainTextEdit 都是针对最普通的 C++
字符串编辑和显示,默认都是白底黑字,没有彩色字体。QLineEdit 按照名字,就是只接受单行普通文本输入,QPlainTextEdit
可以接收多行普通文本输入。<br>
丰富文本编辑控件 QTextEdit 是升级版的编辑控件,支持 HTML 网页的丰富文本编辑,当然也可以利用它编辑普通文本。丰富文本浏览控件
QTextBrowser 是 QTextEdit 的只读版本,并能打开网页链接。<br>
本节主要介绍 QLineEdit,下一节主要介绍 QTextEdit 和 QTextBrowser,学习这些内容之后,使用 QPlainTextEdit
就没什么技术难度了,查看 Qt 助手文档可以轻松学会,所以不专门讲解 QPlainTextEdit 了。<br>
<br>
<div class="os2">5.2.2 QLineEdit 类</div>
<br>
在 Qt 助手索引里输入类名,就可以找到相应的帮助文档。QLineEdit
就如名字一样,接收一行文本输入,编辑器一般都有对文本的复制、粘贴、剪切、撤销、重做等功能,单行编辑控件原生自带这些功能,右击单行编辑控件或者使用
Ctrl+C、Ctrl+V、Ctrl+X 等快捷键都可以使用这些默认功能。<br>
首先看看 QLineEdit 构造函数:<br>
<div class="code">QLineEdit(QWidget * parent = 0)</div>
<div class="code">QLineEdit(const QString & contents, QWidget * parent =
0)</div>
parent 是父窗口指针,第二个构造函数的 contents 是初始化显示的文本。<br>
单行编辑控件最重要的属性就是 text,获取或者修改文本是单行编辑控件最重要的功能。<br>
获取文本的函数:<br>
<div class="code">QString text() const</div>
设置文本的函数:<br>
<div class="code">void setText(const QString &)</div>
默认情况下,单行编辑控件的文本长度限制为 32767,获取单行编辑控件的文本长度限定的函数为:<br>
<div class="code">int maxLength() const</div>
如果希望修改文本长度限定,可以通过函数:<br>
<div class="code">void setMaxLength(int)</div>
<br>
无论是用户从图形界面编辑文本,还是程序内部用代码修改文本,都会触发如下信号:<br>
<div class="code">void textChanged(const QString & text)</div>
关联这个信号,就可以实时跟踪文本的所有变化。<br>
我们之前 4.2.1 节例子用过单行编辑控件和标签控件,使它们的文本同步显示,我们关联的是另一个信号:<br>
<div class="code">void textEdited(const QString & text)</div>
这个信号只根据用户在图形界面的编辑行为触发,如果程序代码里通过函数 setText() ,那么只会触发之前的 textChanged()
信号,不会触发文本编辑信号 textEdited()。所以如果希望追踪文本的所有变化,需要关联 textChanged()
信号,如果只希望跟踪用户在图形界面的编辑更改,那就关联 textEdited() 信号。<br>
当用户从图形界面编辑文本的行为结束时,比如在单行编辑控件里按了回车键或者该控件失去输入焦点(用户转到其他控件操作),单行编辑控件会发出编辑完成信号:<br>
<div class="code">void editingFinished()</div>
另外,单行编辑控件既可以用上面 text() 函数获取全部的文本,也可以选取用户高亮选中的部分文本,通过函数:<br>
<div class="code">QString selectedText() const</div>
因为单行编辑控件文本相对简单,本来文本就不多,所以获取高亮的部分文本情况也比较少。<br>
刚才提到单行编辑控件可以进行复制、粘贴、剪切、撤销、重做等操作,每个操作都有对应的槽函数实现,不过通过代码直接调用这些槽函数情况比较少,就不会一一列举
了,可以通过 Qt 助手查找相应文档。基本情况就介绍这么多,下面通过例子示范单行编辑控件的使用。<br>
<br>
<div class="os2">5.2.3 登录框示例</div>
<br>
登录框主要就是接收用户输入的用户名和密码,在用户点击“登录”按钮之后,将用户名和密码的 Hash 值与软件配置文件或数据库里的值进行比较,然后决定是否允
许登录。<br>
密码框通常是以一排 * 显示的,单行编辑控件可以通过设置属性 echoMode 来显示星号密码。属性 echoMode 是 EchoMode 枚举类型,
主要有四种显示模式:<br>
① QLineEdit::Normal,普通模式,用户输入什么显示什么,这是默认的显示模式。<br>
② QLineEdit::NoEcho,不显示任何东西,这是 Unix/Linux 常用的密码显示模式,用户敲密码时不显示任何文本,这样能隐藏密码的长
度,不被人从屏幕偷窥。<br>
③ QLineEdit::Password,每一个密码字符都用星号显示,这是 Windows 常用的密码显示模式。<br>
④
QLineEdit::PasswordEchoOnEdit,当输入一个密码字符时,短暂显示该字符,然后迅速将该字符显示为星号,方便提示用户当前输入了什么字符,类
似 Android 解锁密码的输入方式。<br>
通过单行编辑控件的函数:<br>
<div class="code">void setEchoMode(EchoMode) </div>
可以设置密码显示模式,一般用 QLineEdit::Password 就可以了。<br>
<br>
顺便说一下关于密码如何保存的问题,现在互联网上各种黑客、广告商盛行,所以密码是绝对不能明文存储的,一般都是将密码文本做 Hash 转换,存储 Hash
散列值作为密码比较的依据,这样避免用户明文密码泄漏。用户如果需要修改密码,那么直接换个 Hash 值就行了。<br>
Qt 自带有计算密码学 Hash 值的类 QCryptographicHash,支持多种多样的散列 Hash
算法,这个类有一个静态函数可以快速计算各种算法的散列值:<br>
<div class="code">QByteArray QCryptographicHash::hash(const QByteArray
& data, Algorithm method)</div>
参数 data 就是输入的明文密码,method 是密码学 Hash 算法枚举,返回值就是求得的 Hash 值,用 QByteArray
存储返回值。Qt 支持所有主流的 Hash 算法,算法枚举很多,具体可以查 QCryptographicHash 类的文档,例子中我们使用
QCryptographicHash::Sha3_256 算法,下面开始本小节的例子。<br>
<br>
打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 login,创建路径 D:\QtProjects\ch05,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
建好项目之后,打开窗体 widget.ui 文件,进入设计模式,按照下图拖入控件:<br>
<center><img src="images/ch05/ch05-02-02.png" alt="ui" width="800"></center>
界面里有两个标签控件、两个单行编辑控件、两个按压按钮。标签控件的文本如图上显示的:“用户名”、“密码”,标签高度调整为
20,这样与单行编辑控件的高度一样,方便与单行编辑控件对齐。<br>
两个单行编辑控件,上面的 objectName 设为 lineEditUser,下面的 objectName 设为
lineEditPassword,并尽量与两个标签控件对齐。<br>
对于下面两个按钮,左边的文本为“登录”,objectName 设为 pushButtonLogin,右边按钮文本为“退出”,objectName 设为
pushButtonExit。调整控件的位置,尽量看起来对齐。<br>
<br>
例子的效果就是点击“登录”按钮时,获取用户名,计算密码的 Hash 值并弹窗显示出来。点击“退出”按钮时,窗口自动关闭。<br>
在图形界面右击两个按钮,在右键菜单选择“转到槽...”,然后为按钮的 clicked() 信号添加槽函数:<br>
<center><img src="images/ch05/ch05-02-03.png" alt="slot"></center>
为两个按钮添加好槽函数之后,保存界面文件,然后回到代码编辑模式,打开头文件 widget.h,添加成员变量:<br>
<div class="code"><span style=" color:#000080;">#ifndef</span><span style=" color:#c0c0c0;">
</span>WIDGET_H
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#define</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">WIDGET_H</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QWidget></span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">namespace</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">:</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">public</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">Q_OBJECT</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">public</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">explicit</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QWidget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>parent<span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">~</span><span style=" font-style:italic; color:#000000;">Widget</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">slots</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonLogin_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_pushButtonExit_clicked</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Ui</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//用户名字符串</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_strUser</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//不能明文保存密码,存储密码</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">hash</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">值</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QByteArray</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_passwordHash</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#endif</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">WIDGET_H</span></pre>
</div>
两个槽函数是刚才从图形界面添加的,这里新增了两个成员变量 m_strUser 保存用户名,m_passwordHash 保存密码的 Hash
值。头文件内容就这些,下面来编辑 widget.cpp ,首先添加头文件包含和构造函数里的代码:<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">"widget.h"</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"ui_widget.h"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QDebug></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QMessageBox></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QCryptographicHash></span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">Widget</span><span style=" color:#000000;">(</span><span
style=" color:#800080;">QWidget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setupUi</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置密码框的显示模式</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">lineEditPassword</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setEchoMode</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QLineEdit</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Password</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::~</span><span
style=" font-style:italic; color:#000000;">Widget</span><span style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
头文件 <QCryptographicHash> 就是专门计算 Hash 值的类。在构造函数里,使用 lineEditPassword 的
setEchoMode() 函数,参数为 QLineEdit::Password ,这样就能轻松将该单行编辑控件变成真正的密码框了。<br>
<br>
接下来是“登录”按钮的槽函数编写:<br>
<div class="code"><span style=" color:#008000;">//登录按钮</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonLogin_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//判断用户名密码是否为空</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">lineEditUser</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">text</span><span
style=" color:#000000;">().</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">||</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span style=" color:#000000;">-></span><span
style=" color:#800000;">lineEditPassword</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">text</span><span style=" color:#000000;">().</span><span
style=" color:#000000;">isEmpty</span><span style=" color:#000000;">()</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">warning</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"警告信息"</span><span style=" color:#000000;">),</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"用户名或密码为空,不能登录。"</span><span style=" color:#000000;">));</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">return</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">}</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//用户名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_strUser</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-></span><span
style=" color:#800000;">lineEditUser</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">text</span><span style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//计算密码</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">Hash</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_passwordHash</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QCryptographicHash</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">hash</span><span style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">ui</span><span style=" color:#000000;">-></span><span
style=" color:#800000;">lineEditPassword</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">text</span><span style=" color:#000000;">().</span><span
style=" color:#000000;">toUtf8</span><span style=" color:#000000;">(),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QCryptographicHash</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">Sha3_256</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//构造消息</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//添加用户名</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strMsg</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span style=" color:#008000;">"用户名:"</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">+</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_strUser</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">+</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span style=" color:#008000;">"\r\n"</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">+</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"密码</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">Hash:"</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//把每个</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">Hash</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">字节转成一对十六进制字符显示</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">256</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">bit</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">对应</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">32</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">字节,变成</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">64</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">个十六进制字符打印</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strMsg</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">+=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">m_passwordHash</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">toHex</span><span style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打印消息</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#000000;">strMsg</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//弹窗显示,注意:实际应用中会将用户名和密码</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">Hash</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">与数据库或配置文件里的做比较,而不是弹窗</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">information</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">tr</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"用户信息"</span><span style=" color:#000000;">),</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strMsg</span><span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
在 on_pushButtonLogin_clicked()
槽函数开始的地方,先对用户名和密码的字符串进行判断,如果字符串是空的,说明没有输入用户名和密码,那就直接提示警告信息,而不做其他操作。
QMessageBox::warning() 静态函数与 QMessageBox::information() 静态函数其实是差不多的,只是一个用于显示
警告信息,另一个用于显示普通信息。<br>
<br>
如果两个字符串都不是空的,那么继续后续代码,用单行编辑控件的 text() 函数提取用户名保存到 m_strUser 变量里面。<br>
因为不能直接存储密码字符串,所以将密码字符串用 QCryptographicHash::hash() 计算 Hash 值存到
m_passwordHash 里面。 QCryptographicHash::hash() 第一个参数是 QByteArray 类型,所以需要将
QString 对象转换成 UTF-8 编码的 QByteArray 对象,利用 toUtf8() 函数即可,第二个参数是 Hash
算法类型,这里用的是 QCryptographicHash::Sha3_256 。该函数会将 QByteArray 对象数据全部计算,得到固定 256
bit (32 字节)的 Hash 值,这个 Hash 是二进制数据流,包含大量不可打印字符。<br>
<br>
接下来我们构造要显示的消息 strMsg ,第一行是 "用户名:" 和用户名字符串,第二行是 "密码 Hash:" 和 Hash
值的十六进制字符串,因为 Hash 值是二进制数据,包含不可打印字符,因此使用 QByteArray 类的 toHex()
函数将每个字节转换成两个十六进制数的字符,比如字节数值 0x7f ,就转成 "7f" 两个字符,然后将这个十六进制字符串添加到 strMsg 。<br>
<br>
最后是用 qDebug() 打印 strMsg ,并弹窗显示 strMsg 。实际应用中并不会弹窗显示用户名和密码 Hash,一般是将用户名与密码
Hash 值与数据库中存储的或配置文件中保存的值进行比较,这里因为还没涉及到数据库和配置文件,所以用弹窗作为示范。<br>
<br>
剩下第二个“退出”按钮的槽函数内容比较简单,如下所示:<br>
<div class="code"><span style=" color:#008000;">//退出按钮</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonExit_clicked</span><span
style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">this</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">close</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
调用窗体的 close() 函数,关闭窗体,因为程序只有一个窗体,关闭之后程序自动退出。<br>
例子代码就这么多,程序运行效果如下图所示:<br>
<center><img src="images/ch05/ch05-02-04.png" alt="run" width="800"></center>
当用户名和密码都是 user 时,就会显示图上的 Hash 值的字符串,strMsg 只有两行文本,而
QMessageBox::information() 显示的却是三行,那是因为 Hash 值的字符串实在太宽了,所以消息框自动把 Hash
值的字符串放到第三行显示了。<br>
如果用户名密码有一个为空,那么点击“登录”按钮会出现警告消息框:<br>
<center><img src="images/ch05/ch05-02-05.png" alt="warning"></center>
警告消息框里面的图标与普通信息消息框不一样,其他的功能都是差不多的。另外还有提示严重错误的消息框,函数为
QMessageBox::critical() ,就是图标不一样,其他的功能和普通消息框差不多。<br>
<br>
<div class="os2">5.2.4 数据验证器和伙伴快捷键</div>
<br>
在用户输入时,可能用到一个功能就是数据验证,限制用户输入非法的取值。比如限定 IPv4 的取值为 0.0.0.0 到 255.255.255.255
,端口取值范围 0 到 65535,而网卡 MAC 地址限定为 48 bit 数值对应的十六进制字符串,比如 AA:BB:CC:DD:EE:FF 。<br>
Qt 针对单行编辑控件,提供三种方式来使用数据验证器:<br>
(1)单行编辑控件自带的输入模板 inputMask:<br>
通过函数设置输入模板,这个输入模板字符串是 QLineEdit 自定义的,应用范围比较局限,功能也相对简单,设置函数为:<br>
<div class="code">void setInputMask(const QString & inputMask)</div>
具体的 inputMask 字符串格式可以查询 QLineEdit 的文档,我们举 MAC 地址的例子,"H"
表示所有的十六进制字符,包括大小写的十六进制字符,而且 "H" 占位的字符不能省略。小写的 "h" 也代表所有十六进制字符,但 "h"
占位是可以省略的字符.<br>
对于 MAC 地址,输入模板为 "HH:HH:HH:HH:HH:HH" 。<br>
<br>
(2)整型数值和浮点数值验证器<br>
针对整数数值,可以用 QIntValidator 类作为验证器,该类常用构造函数为:<br>
<div class="code">QIntValidator(int minimum, int maximum, QObject * parent =
0)</div>
parent 是父对象指针,minimum 是整数下限,maximum
是整数上限,允许的数值是包含两个边界值的,边界之外的数值都不允许输入。QIntValidator 类还有一个 用于修改上下限的函数:<br>
<div class="code">void QIntValidator::setRange(int bottom, int top)</div>
bottom 是下限数值,top 是上限数值。<br>
一般用 new 新建一个整数验证器之后,就可以把验证器设置给单行编辑控件:<br>
<div class="code">void QLineEdit::setValidator(const QValidator * v)</div>
<br>
针对浮点数校验,由 QDoubleValidator 类实现,它常用的构造函数为:<br>
<div class="code">QDoubleValidator(double bottom, double top, int decimals,
QObject * parent = 0)</div>
bottom 是双精度浮点数下限,top 是上限,decimals 是指小数点后的数字位数限定(精度),parent 是父对象指针。修改 浮点数验证器上
下限和精 度的函数为:<br>
<div class="code">virtual void setRange(double minimum, double maximum, int
decimals = 0)</div>
minimum 是下限,maximum 是上限,decimals 是小数点后精度位数。<br>
新建浮点数验证器之后,也是通过 QLineEdit::setValidator() 函数设置给单行编辑控件。<br>
设置好单行编辑控件的数据验证器之后,在用户输入数据时,单行编辑控件自动按照验证器要求,只允许用户输入合法的数据,自动限制不合法的输入。<br>
<br>
(3)正则表达式验证器<br>
正则表达式是最为强大的数据验证和数据筛选武器,正则表达式作为大杀器,几乎无所不能。关于正则表达式的内容有专门的书籍介绍,这里没法介绍这个大杀器。各种编程
语言一般都有支持正则表达式的类库,Qt 提供 QRegExp 类支持正则表达式,正则表达式的验证器类为
QRegExpValidator。一般是先通过字符串构建一个正则表达式:<br>
<div class="code">QRegExp(const QString & pattern, Qt::CaseSensitivity
cs = Qt::CaseSensitive, PatternSyntax syntax = RegExp)</div>
pattern 是正则表达式字符串,cs 指是否大小写敏感,默认是敏感的,syntax 是语法格式,用默认的 RegExp,这是类似 Perl
语言风格的正则表达式。一般可以搜索 IPv4 格式的 Perl 或其他语言的正则表达式,拿过来用即可。<br>
然后根据 QRegExp 构建一个正则表达式验证器:<br>
<div class="code">QRegExpValidator(const QRegExp & rx, QObject * parent
= 0)</div>
最后将 QRegExpValidator 对象通过函数 QLineEdit::setValidator() 函数设置给单行编辑控件就行了。<br>
网上查找关于 IPv4 格式的正则表达式为:<br>
<div class="code">"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}"<br>
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"</div>
上面正则表达式原本是一行,实在太长,拆为两行来写了。C++ 可以自动拼接字符串,因此可以按上面两行来写。<br>
注意其他脚本语言里面 "\" 就是反斜杠,不是转义字符,我们把这个正则表达式变成 C++ 代码中的字符串时,原本的反斜杠字符要用 "\\" 来替换。<br>
<br>
说实话,这个正则挺复杂,IPv6 的更复杂,我们这小节的例子还是用 IPv4 的吧。介绍这个 IPv4 正则表达式的网页链接如下:<br>
<a href="https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html"
target="new">
https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
</a><br> <br>
介绍完三类数据验证器,下面本小节的例子就是围绕 MAC、IP、Port 输入来展开的,顺便给三个单行编辑控件设置伙伴快捷键。<br>
重新打开 QtCreator ,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 netparas,创建路径 D:\QtProjects\ch05,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
建好项目之后,打开窗体 widget.ui 文件,进入设计模式,按照下图拖入控件:<br>
<center><img src="images/ch05/ch05-02-06.png" alt="ui" width="800"></center>
第一行的标签文本为 "&MAC" ,单行编辑控件 objectName 为 lineEditMAC;<br>
第二行的标签文本为 "&IP" ,单行编辑控件 objectName 为 lineEditIP;<br>
第三行的标签文本为 "&Port" ,单行编辑控件 objectName 为 lineEditPort。<br>
将标签控件高度都设置为 20,这样与单行编辑控件一样高,就可以按上图调整位置,对齐所有控件了。这个例子就不弹窗了,我们跟踪三个单行编辑控件的
textChanged() 信号来打印实时的用户输入。<br>
<br>
标签控件里的 "&" 用于设置伙伴快捷键,因为单行编辑控件没法显示自己的快捷键,所以需要通过伙伴标签控件来设置快捷键。"&MAC"
意味着伙伴快捷键为 Alt+M ,"&IP" 快捷键就是 Alt+I ,"&Port" 快捷键是 Alt+P
。当然,快捷键能实现的前提是设置伙伴,我们点击设计模式上面的带有橙色小块的图标,进入伙伴编辑模式:<br>
<center><img src="images/ch05/ch05-02-07.png" alt="buddy" width="800"></center>
在伙伴编辑模式,编辑伙伴关系类似在画图板画线的操作,从标签控件画线到右边的单行编辑控件即可。将三行的标签都设置为对应的单行编辑控件伙伴。设置为伙伴之后,
标签控件就不再显示 "&" ,而是将 "&" 右边第一个字母添加下划线显示,这样伙伴快捷键就设置成功了。<br>
<br>
然后我们点击窗体上方第一个“普通部件编辑模式”图标,回到普通的部件编辑模式,右击每个单行编辑控件,选择右键菜单“转到槽...”,然后为每个单行编辑控件添
加接收 textChanged(QString) 信号的槽函数:<br>
<center><img src="images/ch05/ch05-02-08.png" alt="slot"></center>
添加三个单行编辑控件的槽函数之后,保存界面文件。回到代码编辑模式,这时候 widget.h
头文件已被自动修改,这个头文件不用手动编辑的,下面只是把它的代码贴出来:<br>
<div class="code"><span style=" color:#000080;">#ifndef</span><span style=" color:#c0c0c0;">
</span>WIDGET_H
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#define</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">WIDGET_H</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QWidget></span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">namespace</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">:</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">public</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">Q_OBJECT</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">public</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">explicit</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QWidget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>parent<span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">~</span><span style=" font-style:italic; color:#000000;">Widget</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">slots</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_lineEditMAC_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span>arg1<span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_lineEditIP_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span>arg1<span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_lineEditPort_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span>arg1<span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Ui</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#endif</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">WIDGET_H</span></pre>
</div>
下面我们编辑 widget.cpp 文件的内容,添加例子的功能代码,首先是包含头文件,编辑构造函数:<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">"widget.h"</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"ui_widget.h"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QDebug></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QIntValidator></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QRegExp></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QRegExpValidator></span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">Widget</span><span style=" color:#000000;">(</span><span
style=" color:#800080;">QWidget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setupUi</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">MAC</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">输入模板</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">lineEditMAC</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setInputMask</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"HH:HH:HH:HH:HH:HH"</span><span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//定义</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">IPv4</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">正则表达式,注意 "\\" 就是一个反斜杠字符</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QRegExp</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">re</span><span style=" color:#000000;">(</span><span
style=" color:#008000;">"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建正则表达式验证器</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QRegExpValidator</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">reVali</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QRegExpValidator</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">re</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置给</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">lineEditIP</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">lineEditIP</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setValidator</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">reVali</span><span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建整数验证器</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QIntValidator</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">intVali</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QIntValidator</span><span
style=" color:#000000;">(</span><span style=" color:#000080;">0</span><span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">65535</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置给</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">lineEditPort</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">lineEditPort</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setValidator</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">intVali</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::~</span><span
style=" font-style:italic; color:#000000;">Widget</span><span style=" color:#000000;">()</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
<QIntValidator> 是整数验证器的头文件,<QRegExp> 和 <QRegExpValidator>
是正则表达式验证器用到的头文件。<br>
在构造函数里,我们先用 MAC 地址单行编辑控件的 setInputMask 函数,将输入模板设置为 "HH:HH:HH:HH:HH:HH"
,这样单行编辑控件就会自动根据这个模板来判断输入数据是否合法,并且会自动为用户填充冒号字符,不需要用户自己敲冒号字符了。<br>
<br>
然后定义了 IPv4 正则表达式 re,只用了一个参数,就是正则表达式的字符串形式,其他参数用默认的。<br>
有了正则表达式 re,然后根据 re 新建一个 reVali 验证器。<br>
再将正则表达式验证器设置给 ui->lineEditIP 就行了。setValidator() 函数会自动将验证器的父对象设置为该单行编辑控件,在
单行编辑控件销毁时,该验证器也是随之销毁,所以不用手动 delete。<br>
<br>
在构造函数末尾,端口编辑控件使用整数验证器,这个比较简单,新建一个整数验证器 intVali ,然后把验证器设置给
ui->lineEditPort 就搞定了。<br>
<br>
接下来是三个槽函数的代码,功能都比较简单:<br>
<div class="code"><span style=" color:#808000;">void</span><span style=" color:#c0c0c0;">
</span><span style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">on_lineEditMAC_textChanged</span><span style=" color:#000000;">(</span><span
style=" color:#808000;">const</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QString</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">&</span><span style=" color:#000000;">arg1</span><span
style=" color:#000000;">)</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#008000;">"MAC:</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">"</span><span style=" color:#000000;"><<</span><span
style=" color:#000000;">arg1</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_lineEditIP_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span><span
style=" color:#000000;">arg1</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#008000;">"IP:</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">"</span><span style=" color:#000000;"><<</span><span
style=" color:#000000;">arg1</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_lineEditPort_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span><span
style=" color:#000000;">arg1</span><span style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#008000;">"Port:</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">"</span><span style=" color:#000000;"><<</span><span
style=" color:#000000;">arg1</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
槽函数就是打印当前实时的文本字符串 arg1,对于不同编辑控件,加了相应的前缀用于区分。<br>
<br>
这个例子代码就这么多,下面生成并运行例子看看效果:<br>
<center><img src="images/ch05/ch05-02-09.png" alt="run" width="800"></center>
程序运行时,伙伴快捷键自动生效:<br>
按 Alt+M ,自动切换到 MAC 地址编辑控件;<br>
按 Alt+I ,自动切换到 IP 地址编辑控件;<br>
按 Alt+P ,自动切换到端口编辑控件。<br>
示范的例子标签文本都是英文的,如果是中文文本,以端口为例,可以设置为 "端口(&P)" ,这样快捷键也是 Alt+P。<br>
三个单行编辑控件的验证器功能大家自行测试,看看非法数据能否输入。<br>
(正常情况下,非法数据是无法输入的,也不会触发 textChanged 信号。)<br>
<br>
<div class="os2">5.2.5 单词补全</div>
<br>
在进行文本编辑时,编辑器常用的一个功能就是单词补全,比如 Linux 系统命令行里面输入命令或文件名头几个字符,然后按 Tab
键就会实现命令或文件名的补 全。单行编辑控件也有类似功能,通过设置单词补全器 QCompleter 实现。<br>
QCompleter 常用构造函数为:<br>
<div class="code">QCompleter(QAbstractItemModel * model, QObject * parent =
0)</div>
<div class="code">QCompleter(const QStringList & list, QObject * parent
= 0)</div>
parent 是父对象指针,第一个构造函数的 model
是指数据条目的模型,这个在后续章节才会学习。第二个构造函数是本小节使用的,根据一个字符串列表来生成单词补全器。<br>
单词补全器可以设置单词是否大小写敏感,默认是敏感的,区分大小写:<br>
<div class="code">void setCaseSensitivity(Qt::CaseSensitivity
caseSensitivity)</div>
Qt::CaseSensitivity 枚举类型有两个枚举常量,Qt::CaseInsensitive
是大小写不敏感,Qt::CaseSensitive 是敏感。<br>
<br>
在用户输入单词头几个字符时,单行编辑控件可以根据单词补全器匹配相似的单词并显示出来,补全匹配的单词显示模式(CompletionMode)有三种:<br>
① QCompleter::PopupCompletion,是指正常的弹出单词列表显示。<br>
② QCompleter::InlineCompletion,不弹出列表,将最接近的一个单词显示到编辑框里,补全的后半截字符用选中的高亮显示。<br>
③ QCompleter::UnfilteredPopupCompletion,如名字一样,把单词补全器里所有可能的单词都列出来,不做匹配筛选。<br>
默认情况下都是第一个 QCompleter::PopupCompletion,显示匹配筛选后的简短列表。可以通过如下函数改变补全单词的显示模式:<br>
<div class="code">void setCompletionMode(CompletionMode mode) </div>
<br>
弹出的单词补全列表默认不排序的,如果希望字符串列表是有序的,可以提前调用 QStringList 排序函数:<br>
<div class="code">void QStringList::sort(Qt::CaseSensitivity cs =
Qt::CaseSensitive)</div>
参数 cs 指定排序时大小写是否敏感。<br>
<br>
关于单词补全器的内容先介绍这么多,以后用到模型的时候再讲关于模型的部分。生成单词补全器之后,就可以通过如下函数把补全器设置给单行编辑控件:<br>
<div class="code">void QLineEdit::setCompleter(QCompleter * c)</div>
如果 c 是存在的补全器,那么 c 就会设置给单行编辑控件;如果 c 是 NULL,那么将会取消单行编辑控件之前的补全器,就没有单词补全了。<br>
<br>
下面开始单词补全的例子,重新打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 completer,创建路径 D:\QtProjects\ch05,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
建好项目之后,打开窗体 widget.ui 文件,进入设计模式,按照下图拖入控件:<br>
<center><img src="images/ch05/ch05-02-10.png" alt="ui" width="800"></center>
也是三个标签控件和三个单行编辑控件,标签控件的大小设置为宽度 80,高度 20,这样能足够显示文本,并利于对齐。<br>
第一行的标签文本为 "&DayOfWeek",单行编辑控件的 objectName 为 lineEditDayOfWeek。<br>
第二行的标签文本为 "&Year",单行编辑控件的 objectName 为 lineEditYear。<br>
第三行的标签文本为 "何夕(&H)",单行编辑控件的 objectName 为 lineEditHeXi。<br>
调整控件位置,尽量让行、列都对齐。<br>
<br>
标签文本的 "&" 都是用于设置伙伴快捷键的,可以按上面小节一样的操作,设置伙伴关系:<br>
<center><img src="images/ch05/ch05-02-11.png" alt="buddy" width="800"></center>
伙伴设置好之后,"&" 就变成快捷键字母的下划线,比如第三行单行编辑控件的快捷键就是 Alt+H 。<br>
然后回到普通部件编辑模式,为三个单行编辑控件添加接收 textChanged(QString) 信号的槽函数:<br>
<center><img src="images/ch05/ch05-02-12.png" alt="slot"></center>
三个槽函数都添加好之后,保存界面文件,回到代码编辑模式。头文件 widget.h 不需要手动修改的,按照自动生成的就可以了,下面只是把代码贴出来:<br>
<div class="code"><span style=" color:#000080;">#define</span><span style=" color:#c0c0c0;">
</span><span style=" color:#000080;">WIDGET_H</span>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QWidget></span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">namespace</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">class</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Widget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">:</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">public</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">Q_OBJECT</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">public</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">explicit</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QWidget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>parent<span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">~</span><span style=" font-style:italic; color:#000000;">Widget</span><span
style=" color:#000000;">();</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">slots</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_lineEditDayOfWeek_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span>arg1<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_lineEditYear_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span>arg1<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">on_lineEditHeXi_textChanged</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">&</span>arg1<span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#808000;">private</span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Ui</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#endif</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">WIDGET_H</span></pre>
</div>
我们打开 widget.cpp 文件,添加需要的功能代码,首先是头文件包含和构造函数(代码里的字符串没用 tr
函数包裹,是因为都不做翻译,就用固定的字符串):<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">"widget.h"</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"ui_widget.h"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QDebug></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QCompleter></span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">Widget</span><span style=" color:#000000;">(</span><span
style=" color:#800080;">QWidget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setupUi</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//星期单词列表</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QStringList</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">listDayOfWeek</span><span
style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">listDayOfWeek</span><span
style=" color:#000000;"><<</span><span style=" color:#008000;">"Monday"</span><span
style=" color:#000000;"><<</span><span style=" color:#008000;">"Tuesday"</span><span
style=" color:#000000;"><<</span><span style=" color:#008000;">"Wednesday"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;"><<</span><span
style=" color:#008000;">"Thursday"</span><span style=" color:#000000;"><<</span><span
style=" color:#008000;">"Friday"</span><span style=" color:#000000;"><<</span><span
style=" color:#008000;">"Saturday"</span><span style=" color:#000000;"><<</span><span
style=" color:#008000;">"Sunday"</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//构建补全器</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QCompleter</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">cpDayOfWeek</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QCompleter</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">listDayOfWeek</span><span
style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//大小写不敏感</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">cpDayOfWeek</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setCaseSensitivity</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span
style=" color:#800080;">CaseInsensitive</span><span style=" color:#000000;">);</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//设置给</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">lineEditDayOfWeek</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">lineEditDayOfWeek</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setCompleter</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">cpDayOfWeek</span><span
style=" color:#000000;">);</span></pre>