-
Notifications
You must be signed in to change notification settings - Fork 7
/
ch11-01.htm
3171 lines (2046 loc) · 200 KB
/
ch11-01.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>ch11-01</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">11.1 QWidget 多窗口使用</div>
<br>
本节介绍基于 QWidget
自定义的多窗口程序,定制子窗口并弹窗显示,在多窗口之间使用信号和槽机制进行多窗口之间的数据传递。多窗口程序可以采用新建子窗口的方式,也可以集成之前开发的窗口模块
作为子窗口,本节通过新建和集成两种方式展示子窗口的使用。 <br>
<br>
<div class="os2">11.1.1 QWidget 类</div>
<br>
QWidget 是用户界面所有控件和窗口的基类,涵盖控件和窗口所有基本的功能,比如界面绘制显示、鼠标键盘事件处理等,本节仅介绍一部分窗口显示常用的功能函
数。<br>
(1)构造函数<br>
<div class="code">QWidget(QWidget * parent = 0, Qt::WindowFlags f = 0)</div>
参数 parent 如果为默认值 0,也就是 NULL,那么新建的 QWidget 对象就是独立的窗口,独立窗口有自己的标题栏和边框;<br>
如果指定 parent 为已有的窗口或控件,那么新建的 QWidget 就是子控件,子控件的显示受制于父窗口或父控件。<br>
本节就是专门讲解 QWidget 独立窗口的工作模式,在新建窗口时,不设置 parent 指针或者设为 NULL。<br>
Qt::WindowFlags 可以控制 QWidget 对象的多种工作类型,比如作为窗口、对话框、控件、菜单显示等等,通常不需要修改窗口标志位,每个功
能控件都会自行设置合适的工作类型。<br>
<br>
(2)显示与隐藏函数<br>
我们通过 QtCreator 新建的窗口会有默认的标题栏文本和默认尺寸,可以直接在主窗口调用子窗口的显示函数:<br>
<div class="code">void QWidget::show() //槽函数,显示窗口<br>
void QWidget::hide() //槽函数,隐藏窗口<br>
bool isVisible() const //是否处于显示状态<br>
virtual void setVisible(bool visible) //控制窗口显示或隐藏</div>
show() 是显示窗口槽函数,hide() 是隐藏窗口槽函数,可以通过信号和槽的关联方便控制窗口显示状态,setVisible(bool
visible) 一样可以控制窗口显示或隐藏,参数 true 代表显示, false 代表隐藏。<br>
通常新的子窗口会显示到主窗口的上层,多个窗口的显示可能出现区域重叠,上层的窗口会遮挡下层窗口显示,例如:<br>
<center> <img src="images/ch11/ch11-01-01.png" alt="multi01"></center>
窗口本身是二维显示的,横轴 X, 纵轴 Y,多个窗口的上下层叠加,属于 Z 轴排列,上层的显示会遮挡下层窗口。<br>
控制窗口在 Z 轴的叠加使用下面两个函数:<br>
<div class="code">void QWidget::raise()
//槽函数,将本窗口置于顶层显示<br>
void QWidget::lower() //槽函数,将本窗口置于底层显示</div>
raise() 是将窗口放在本程序所有窗口的 Z 轴最上面显示,lower() 则是放到最底层显示。<br>
用户鼠标点击也会自动切换窗口的 Z 轴位置,鼠标最新点击的窗口通常优先在 Z 轴顶层显示。<br>
程序的多个窗口通常同一时刻只有一个窗口处于活跃状态,就是用户鼠标键盘输入的焦点,鼠标点击哪个窗口,哪个窗口自动显示到最顶层,使用下面函数可以
激活窗口,获 取输入焦点:<br>
<div class="code">void QWidget::activateWindow()
//激活本窗口,注意本窗口必须处于显示状态才有用<br>
bool isActiveWindow() const
//判断是否为活跃状态</div>
也可以使用 raise() 激活窗口获取输入焦点,处于顶层显示。<br>
<br>
对于窗口,如果用户点击标题栏的关闭按钮 X,或者程序调用关闭函数:<br>
<div class="code">bool QWidget::close()</div>
窗口就会被关闭,关闭窗口函数首先会隐藏窗口,然后会触发 QCloseEvent,在这个事件里面可以处理关闭窗口的事务。close()
函数默认情况下不会销毁窗口,当Qt 图形界面程序的所有窗口被关闭时,程序会自动结束,这时才会销毁所有窗口。子窗口调用 close()
函数之后,子窗口对象默认情况下仍保留内存空间,还是一直存在的,成员变量和成员函数可以照常使用,可以通过 show() 函数重新显示。<br>
<br>
QWidget 窗口标题栏默认有最小化、最大化和关闭按钮,用户点击这些按钮会控制窗口的显示形态,通过函数也可以控制窗口的最大化最小化显示:<br>
<div class="code">void QWidget::showMinimized() //槽函数,最小化显示<br>
void QWidget::showMaximized() //槽函数,最大化显示,标题栏和窗口主体都显示,占据桌面最大显示区域<br>
void QWidget::showNormal() //槽函数,正常尺寸显示<br>
void QWidget::showFullScreen() //槽函数,全屏显示,标题栏隐藏,将窗口主体铺满屏幕</div>
程序可以通过函数获取窗口的显示状态,如 isMinimized()、isMaximized()
、isFullScreen()、isVisible()、isHidden() 等。<br>
默认情况下,程序的多个窗口之间是显示优先级是平等的(非模态显示),有一种特殊的显示方式,叫模态显示,这种窗口会独占显示焦点,强制显示在最上
层,不关闭模态窗口,就无法操作底层其他窗口。QWidget 有个特殊属性 windowModality 控制窗口的模态显示:<br>
<div class="code">Qt::WindowModality windowModality()
const //获取模态状态<br>
void setWindowModality(Qt::WindowModality
windowModality) //设置模态状态<br>
bool isModal() const //是否为模态窗口</div>
Qt::WindowModality 枚举类型有三种:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 220px;" align="center"><b>Qt::WindowModality 枚举常量</b></td>
<td style="width: 160px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>Qt::NonModal</td>
<td> 0 </td>
<td> 非模态窗口,不会阻塞其他窗口输入。 </td>
</tr>
<tr class="d1">
<td>Qt::WindowModal</td>
<td> 1</td>
<td> 窗口级模态,在兄弟级别、父级窗口及祖父以上级别窗口中,阻塞其他窗口,独占输入焦 点。 </td>
</tr>
<tr>
<td>Qt::ApplicationModal</td>
<td> 2</td>
<td> 应用程序级模态,在本应用程序所有窗口中,阻塞其他窗口,独占输入焦点。 </td>
</tr>
</tbody>
</table>
<br>
模态窗口一般设置为 Qt::ApplicationModal 即可,就是独占本程序的输入焦点,模态窗口不关闭,其他窗口都不能使用。<br>
设置模态窗口时,要注意先设置模态属性,然后再显示窗口;<br>
如果窗口已经显示了,再设置模态不会即刻生效,需要调用 hide() 隐藏窗口,然后重新 show() 显示窗口。<br>
模态窗口显示举例:<br>
<div class="code">
pModWnd->setWindowModality(Qt::ApplicationModal); //模态窗口,会阻塞其他窗口<br>
pModWnd->show(); //模态窗口总是显示在最顶层,并且独占输入焦点</div>
<br>
非模态窗口显示举例:
<div class="code"> pNormalWnd->show();
//普通窗口显示,多个窗口都能操作,不会阻塞其他窗口<br>
pNormalWnd->raise(); //将窗口置于顶层显示,方便用户操作</div>
<br>
(3)标题栏设置函数<br>
窗口标题栏可以设置文本、图标,标题栏文本也就是窗口名称,方便直接说明窗口功能:<br>
<div class="code">QString windowTitle()
const //获取标题栏文本<br>
void setWindowTitle(const QString &) //设置标题栏文本<br>
QIcon windowIcon() const
//获取标题栏图标<br>
void setWindowIcon(const QIcon & icon)
//设置标题栏图标<br>
QString windowIconText() const //获取图标的文本<br>
void setWindowIconText(const QString &) //设置图标的文本</div>
<br>
(4)窗口尺寸位置设置函数<br>
用户使用鼠标拉动窗口边框可以改变窗口尺寸,拖动标题栏可以控制窗口位置,通过函数也可以获取或修改窗口尺寸位置,相关函数如下面两个表格所示:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 320px;" align="center"><b>窗口尺寸函数</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>QSize size() const</td>
<td> 获取窗口客户区尺寸。 </td>
</tr>
<tr class="d1">
<td>void resize(int w, int h)</td>
<td> 根据宽度高度设置窗口尺寸。 </td>
</tr>
<tr>
<td>void resize(const QSize &)</td>
<td> 设置窗口尺寸。 </td>
</tr>
<tr class="d1">
<td>int width() const</td>
<td> 获取当前宽度。 </td>
</tr>
<tr>
<td>int height() const</td>
<td> 获取当前高度。 </td>
</tr>
<tr class="d1">
<td>QSize minimumSize() const</td>
<td> 获取最小尺寸。 </td>
</tr>
<tr>
<td>void setMinimumSize(const QSize &)</td>
<td> 设置最小尺寸。 </td>
</tr>
<tr class="d1">
<td>void setMinimumSize(int minw, int minh)</td>
<td> 设置最小尺寸。 </td>
</tr>
<tr>
<td>int minimumWidth() const</td>
<td style="height: 16px;"> 获取最小宽度。 </td>
</tr>
<tr class="d1">
<td>void setMinimumWidth(int minw)</td>
<td> 设置最小宽度。 </td>
</tr>
<tr>
<td>int minimumHeight() const</td>
<td> 获取最小高度。 </td>
</tr>
<tr class="d1">
<td>void setMinimumHeight(int minh)</td>
<td> 设置最小高度。 </td>
</tr>
<tr>
<td>QSize maximumSize() const<br>
</td>
<td> 获取最大尺寸。 </td>
</tr>
<tr class="d1">
<td>void setMaximumSize(const QSize &)</td>
<td> 设置最大尺寸。 </td>
</tr>
<tr>
<td>void setMaximumSize(int maxw, int maxh)<br>
</td>
<td> 设置最大尺寸。 </td>
</tr>
<tr class="d1">
<td style="height: 16px;">int maximumWidth() const</td>
<td> 获取最大宽度。 </td>
</tr>
<tr>
<td>void setMaximumWidth(int maxw)<br>
</td>
<td> 设置最大宽度。 </td>
</tr>
<tr class="d1">
<td>int maximumHeight() const</td>
<td> 获取最大高度。 </td>
</tr>
<tr>
<td>void setMaximumHeight(int maxh)<br>
</td>
<td> 设置最大高度。 </td>
</tr>
<tr class="d1">
<td>QRect rect() const</td>
<td> 获取窗口客户区矩形,等同于 QRect(0, 0, width(), height()) 。 </td>
</tr>
</tbody>
</table>
<br>
QSize 包括两个数值:宽度 width() ,高度 height() 。<br>
QRect 矩形包括四个数值:左上角起点横坐标 x(),左上角起点纵坐标 y() ,矩形宽度 width() ,矩形高度 height() 。<br>
<br>
移动窗口或获取窗口位置的函数:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 320px;" align="center"><b>窗口位置函数</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>QPoint pos() const</td>
<td>获取窗口左上角起点位置坐标。</td>
</tr>
<tr class="d1">
<td>void move(int x, int y)</td>
<td style="height: 16px;">移动窗口位置,使左上角起点到指定坐标。</td>
</tr>
<tr>
<td>void move(const QPoint &)</td>
<td>移动窗口位置,使左上角起点到指定坐标。</td>
</tr>
<tr class="d1">
<td>int x() const</td>
<td>窗口左上角起点位置的横轴坐标。</td>
</tr>
<tr>
<td>int y() const</td>
<td style="height: 16px;">窗口左上角起点位置的纵轴坐标。</td>
</tr>
<tr class="d1">
<td>const QRect & geometry() const</td>
<td>窗口客户区几何矩形(不含标题栏边框)。</td>
</tr>
<tr>
<td>void setGeometry(int x, int y, int w, int h)</td>
<td style="height: 16px;">设置窗口客户区几何矩形,同时设置坐标和尺寸。</td>
</tr>
<tr class="d1">
<td>void setGeometry(const QRect &)</td>
<td>设置窗口客户区几何矩形。</td>
</tr>
<tr>
<td>QRect frameGeometry() const</td>
<td style="height: 16px;">窗口包含标题栏边框的整体几何矩形。</td>
</tr>
<tr class="d1">
<td>QSize frameSize() const</td>
<td>窗口包含标题栏边框的整体尺寸。</td>
</tr>
</tbody>
</table>
<br>
<span style="font-weight: bold;">窗口尺寸位置有些函数的计算包含标题和边框,例如:<br>
x(), y(), frameGeometry(), pos(), move() 。<br>
另一些函数计算不包括标题栏和边框,就是单指客户区尺寸位置:<br>
geometry(), width(), height(), rect(), size() 。</span><br>
<br>
通过下图直观说明尺寸位置计算:<br>
<center> <img src="images/ch11/ch11-01-02.png" alt="geo"></center>
绿色箭头包含标题栏边框,是完整的窗口矩形计算,紫色的箭头是窗口客户区矩形计算。<br>
一般来说,移动窗口位置时,我们按照窗口整体来计算;<br>
而缩放窗口尺寸时,按照窗口客户区来计算。<br>
<br>
<div class="os2">11.1.2 新建窗口类方式</div>
<br>
下面我们通过一个密码管理工具例子,学习新建窗口类的方式,使用多个窗口。<br>
主窗口显示用户名和密码哈希值列表,通过新建的子窗口来完成修改用户密码的功能。<br>
我们打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 passwordtool,创建路径 D:\QtProjects\ch11,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,<span style="font-weight: bold;">注意修改主窗口类名为 MainWidget,</span>这
样与后续的子窗口类名作区分,然后点击下一步;<br>
④项目管理不修改,点击完成。<br>
主窗口类名为 MainWidget,对应的界面文件、头文件、源文件名就是
mainwidget.ui、mainwidget.h、mainwidget.cpp 。<br>
接下来我们在项目管理器右击项目根 passwordtool ,右键菜单选择“添加新文件...”,进入新建文件对话框:<br>
<center> <img src="images/ch11/ch11-01-03.png" alt="new1"></center>
在上面对话框左边一栏选择 “Qt”,然后在中间一栏选择“Qt设计师界面类”,然后点击右下角“Choose...”按钮,进入Qt设计师界面类的选择界面:<br>
<center> <img src="images/ch11/ch11-01-04.png" alt="new2"></center>
在中间上半区选择“Widget”,然后点击“下一步”按钮,进入类名编辑界面:<br>
<center> <img src="images/ch11/ch11-01-05.png" alt="new3"></center>
我们只需要把类名修改为 FormChangePassword ,下面的头文件、源文件、界面文件名自动修改,不需要手动调整,修改类名之后点击“下一步”,<br>
<center> <img src="images/ch11/ch11-01-06.png" alt="new4"></center>
项目管理界面不用动,直接点击“完成”按钮。这样项目就增加了新类的文件:<br>
formchangepassword.cpp,formchangepassword.h,formchangepassword.ui。<br>
现在我们有两套界面类,一套是 MainWidget 类主窗口的文件,另一套是 FormChangePassword 类子窗口的文件。<br>
我们从主窗口开始编辑,我们打开 mainwidget.ui 文件,然后拖入控件:<br>
<center> <img src="images/ch11/ch11-01-07.png" alt="mainui01" width="800"></center>
第一行控件分别是标签“用户名”,单行编辑器 lineEditUser,标签“密码”,单行编辑器 lineEditPassword,“添加新用户”按钮
pushButtonAddUser 。<br>
第二行左边是列表控件 listWidgetShow ,右边是两个按钮,“修改用户密码”按钮
pushButtonChangePassword,“删除选定用户”按钮 pushButtonDelUser 。“修改用户密码”按钮就是负责弹出子窗口的功
能按钮。<br>
第一行控件按照水平布局;<br>
第二行先将 pushButtonChangePassword、pushButtonDelUser 两个按钮垂直布局,然后再与
listWidgetShow 进行水平布局,如下图所示:<br>
<center> <img src="images/ch11/ch11-01-08.png" alt="mainui02" width="800"></center>
然后我们选中主窗口 MainWidget,点击上面垂直布局按钮,主窗口的主布局器是垂直布局:<br>
<center> <img src="images/ch11/ch11-01-09.png" alt="mainui03" width="800"></center>
布局完成后,我们修改窗口的尺寸为 518* 300。<br>
然后我们依次右键点击三个按钮,在右键菜单为它们添加 clicked() 信号对应槽函数:<br>
<center> <img src="images/slots/buttonclicked.png" alt="slot"></center>
添加好主界面三个按钮的槽函数之后,我们保存并关闭 mainwidget.ui 文件。<br>
<br>
接下来我们打开子窗口的界面文件 formchangepassword.ui ,拖入如下控件:<br>
<center> <img src="images/ch11/ch11-01-10.png" alt="childui01" width="800"></center>
第一行是标签“用户名”,单行编辑器 lineEditUser;<br>
第二行是标签“旧密码”,单行编辑器 lineEditOldPassword;<br>
第三行是标签“新密码”,单行编辑器 lineEditNewPassword;<br>
第四行是标签“新密码确认”,单行编辑器 lineEditNewPassword2;<br>
第五行是“修改密码”按钮 pushButtonChange,按钮尺寸拉宽,与上一行两个控件的累计宽度差不多 。<br>
在右边对象树,选中窗口 FormChangePassword ,然后点击上面的 网格布局器,该窗口使用一个网格布局即可,设置布局后把窗口大小设置为
280 * 240 ,如下图所示:<br>
<center> <img src="images/ch11/ch11-01-11.png" alt="childui02" width="800"></center>
布局设置完成后,我们右击子窗口的 “修改密码”按钮,为该按钮也添加 clicked() 信号对应槽函数 。<br>
我们右击添加的槽函数自动归属于各自的窗口类,在主窗口右击添加的槽函数自动放到主窗口类,在子窗口右击添加的槽函数自动放到子窗口类。<br>
按钮的槽函数都添加完成后,我们保存 formchangepassword.ui 文件并关闭该文件。<br>
<br>
下面我们先从主窗口代码开始编辑,首先是 mainwidget.h 头文件:<br>
<div class="code"><span style=" color:#000080;">#ifndef</span><span style=" color:#c0c0c0;">
</span>MAINWIDGET_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;">MAINWIDGET_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=" 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><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:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QMap></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:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"formchangepassword.h"</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:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QListWidget></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;"><QListWidgetItem></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;">MainWidget</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;">MainWidget</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;">MainWidget</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;">MainWidget</span><span
style=" color:#000000;">();</span><span style=" color:#c0c0c0;"> </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:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">UpdateListShow</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;">signals</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:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">SendOldUserPassword</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span>strUser<span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QByteArray</span><span
style=" color:#c0c0c0;"> </span>baOldHash<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_pushButtonAddUser_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_pushButtonChangePassword_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_pushButtonDelUser_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:#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;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">RecvNewUserPassword</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span>strUser<span style=" color:#000000;">,</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QByteArray</span><span
style=" color:#c0c0c0;"> </span>baNewHash<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;">MainWidget</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;">QMap</span><span
style=" color:#000000;"><</span><span style=" color:#800080;">QString</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QByteArray</span><span
style=" color:#000000;">></span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_mapUserAndHash</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;">FormChangePassword</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">m_pFormChild</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:#808000;">void</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">Init</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>
<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;">MAINWIDGET_H</span></pre></div>
我们添加了多个类的头文件包含,QCryptographicHash 类专门用于密码哈希值计算,涵盖常见的密码哈希算法,比如
MD5、SHA256
等,密码一般不建议明文直接存储,容易泄密,所以都是将密码通过哈希算法生成哈希值存储。哈希算法是单向计算函数,可以从明文推算哈希值密文,但是反过来难以计算,从而实
现较为安全的密码存储方式。密码比对时,不需要比对明文密码,只需要验证两个密码的哈希值是否一致。<br>
我们添加 QMap 模板类声明,用于保存用户名和密码哈希值的键值对;formchangepassword.h
是子窗口类的头文件;QListWidget 和 QListWidgetItem 是列表控件和列表条目的类。<br>
在 MainWidget 类声明中,我们手动添加更新列表控件显示的函数 UpdateListShow()。<br>
手动添加信号 SendOldUserPassword(QString strUser, QByteArray
baOldHash),用于给修改密码子窗口发送用户名和旧密码哈希值。<br>
三个按钮的槽函数是之前界面文件编辑时添加的,后面我们手动添加槽函数 RecvNewUserPassword(QString strUser,
QByteArray baNewHash),用于从子窗口接收用户名和修改后的新密码哈希值。<br>
我们添加 m_mapUserAndHash 模板类对象,保存用户名和密码哈希值的键值对;<br>
m_pFormChild 是子窗口的指针,用于弹窗修改用户的密码;<br>
Init() 是用于窗口初始化的代码,在该函数里面新建子窗口。<br>
<br>
例子中主窗口和子窗口通过信号和槽函数交互数据,如下图所示:<br>
<center> <img src="images/ch11/ch11-01-12.png" alt="sig-slot" width="600"></center>
需要发送数据时,通过 emit 触发信号即可。<br>
下面我们分段编辑主窗口的源文件 mainwidget.cpp,首先是构造函数和初始化函数内容:<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"mainwidget.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_mainwidget.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;"><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;"><QDebug></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;">MainWidget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">MainWidget</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;">MainWidget</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=" 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;">Init</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;">MainWidget</span><span style=" color:#000000;">::~</span><span
style=" font-style:italic; color:#000000;">MainWidget</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;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pFormChild</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pFormChild</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">NULL</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;">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>
<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:#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:#808000;">void</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">MainWidget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">Init</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:#000000;">setWindowTitle</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></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="-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:#800000;">m_pFormChild</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">NULL</span><span style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//初始化为</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">NULL</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;">parent</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">必须是</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">0</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">或</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">NULL</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_pFormChild</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;">FormChangePassword</span><span
style=" color:#000000;">(</span><span style=" color:#000080;">NULL</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:#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;">connect</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:#808000;">SIGNAL</span><span
style=" color:#000000;">(</span>SendOldUserPassword<span style=" color:#000000;">(</span><span
style=" color:#800080;">QString</span><span style=" color:#000000;">,</span><span
style=" color:#800080;">QByteArray</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;">m_pFormChild</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">SLOT</span><span
style=" color:#000000;">(</span>RecvOldUserPassword<span style=" color:#000000;">(</span><span
style=" color:#800080;">QString</span><span style=" color:#000000;">,</span><span
style=" color:#800080;">QByteArray</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:#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;">connect</span><span
style=" color:#000000;">(</span><span style=" color:#800000;">m_pFormChild</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">SIGNAL</span><span
style=" color:#000000;">(</span>SendNewUserPassword<span style=" color:#000000;">(</span><span
style=" color:#800080;">QString</span><span style=" color:#000000;">,</span><span
style=" color:#800080;">QByteArray</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;">this</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">SLOT</span><span
style=" color:#000000;">(</span>RecvNewUserPassword<span style=" color:#000000;">(</span><span
style=" color:#800080;">QString</span><span style=" color:#000000;">,</span><span
style=" color:#800080;">QByteArray</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:#000000;">}</span></pre></div>
构造函数末尾添加了 Init() 函数调用,析构函数里面添加了一行删除子窗口对象的代码。<br> Init() 函数首先设置主窗口的标题栏文本为 "用户名密码管理工具" ;<br>将密码编辑框的回显模式修改为 QLineEdit::Password ,就是隐藏输入的字符,用星号或者黑圆点代替;<br>我们先将 m_pFormChild 初始化为 NULL 空指针,然后新建子窗口对象,保存到 m_pFormChild,新建窗口时,参数里的 parent 必须为 0 或 NULL;<br>然后我们将主窗口和子窗口的信号、槽函数进行关联,主窗口将用户名、旧密码传递给子窗口,子窗口修改密码后,再将用户名和新密码回传给主窗口。<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;">MainWidget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">UpdateListShow</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:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">listWidgetShow</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">clear</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:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">nCount</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">m_mapUserAndHash</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">count</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;">//获取所有key,就是用户名</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;">QList</span><span
style=" color:#000000;"><</span><span style=" color:#800080;">QString</span><span
style=" color:#000000;">></span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">listKeys</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">m_mapUserAndHash</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">keys</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;">for</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">i</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:#000000;">i</span><span
style=" color:#000000;"><</span><span style=" color:#000000;">nCount</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">i</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;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curKey</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">listKeys</span><span style=" color:#000000;">[</span><span
style=" color:#000000;">i</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;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strTemp</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curKey</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">+</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"\t"</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_mapUserAndHash</span><span style=" color:#000000;">[</span><span
style=" color:#000000;">curKey</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:#800000;">listWidgetShow</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">addItem</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strTemp</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:#000000;">}</span></pre></div>
我们先清空列表控件旧的内容,然后获取用户密码键值对的计数,获取所有的键,也就是用户名列表;<br>然后循环处理映射对象中每个键值对,将用户名和密码哈希值通过 "\t" 拼接成一个字符串,添加为列表控件的一行。<br>循环结束之后,就完成了列表控件的更新。<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;">MainWidget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonAddUser_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:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strNewUser</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><span
style=" color:#000000;">trimmed</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;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strPassword</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;">lineEditPassword</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">text</span><span style=" color:#000000;">().</span><span
style=" color:#000000;">trimmed</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;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strNewUser</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><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strPassword</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;">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;">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:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_mapUserAndHash</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">contains</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strNewUser</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;">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;">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:#800080;">QByteArray</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">baNewHash</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:#000000;">strPassword</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;">Sha256</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;">//二进制哈希转为Hex字符串</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;">baNewHash</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">baNewHash</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">toHex</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_mapUserAndHash</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">insert</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strNewUser</span><span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">baNewHash</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:#000000;">UpdateListShow</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>
该函数先获取用户名和密码的字符串,字符串剔除两端的空白;<br>判断用户名 strNewUser 和密码 strPassword 字符串是否为空,如果有一个为空就弹出信息框提示,然后返回;<br>只有当用户名和密码字符串都不空时,进入后续的处理。<br>
判断 strNewUser 是否为映射对象已有的键,就是检查用户名是否重复,如果重复就弹出信息框提示,然后返回;<br>当没有重复用户名时,才进行后续的添加操作。<br>我们调用静态函数 QCryptographicHash::hash() 计算密码的 SHA256 哈希值,直接得到的字节数组是二进制格式,不便于显示,因此转为 Hex 十六进制字符串,存到 baNewHash,例如原本一字节 0xa1 的二进制转为两个字符 "a1" 。<br>SHA256 哈希值原本 256 比特(32 字节),转换后就是 64 个十六进制字符。<br>我们将用户名和新的哈希字符串存到映射对象 m_mapUserAndHash,并调用 UpdateListShow() 更新列表控件显示。<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;">MainWidget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonDelUser_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;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curIndex</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;">listWidgetShow</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">currentRow</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;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curIndex</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;"><</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</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:#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:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">curItem</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;">listWidgetShow</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">item</span><span style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curIndex</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:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curItem</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">isSelected</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</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;">{</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;">curLine</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curItem</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:#800080;">QStringList</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curKeyValue</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curLine</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">split</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">'\t'</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:#800000;">m_mapUserAndHash</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">remove</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curKeyValue</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:#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;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">listWidgetShow</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">takeItem</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">curIndex</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:#808000;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curItem</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">NULL</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:#000000;">}</span></pre></div>
我们获取列表控件的当前行号,如果行号为 -1 就不处理;<br>行号合法时,我们获取该行的条目存到 curItem 指针;<br>判断该条目是否处于选中状态,只有选中该条目的情况才进行删除操作:<br>获取该行条目的文本,使用 '\t' 切分字符串,切分后形成两个字符串,第 0 段是用户名,第 1 段是密码哈希字符串;<br>我们根据用户名删除映射对象里匹配的键值对,就删除了该用户和哈希值;<br>从列表控件卸下该行条目,并手动删除卸下条目的内存,这样就完成了用户的删除和界面列表控件的更新。<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;">MainWidget</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">on_pushButtonChangePassword_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;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curIndex</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;">listWidgetShow</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">currentRow</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;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curIndex</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;"><</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000080;">0</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:#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:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">curItem</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;">listWidgetShow</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">item</span><span style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curIndex</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:#808000;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curItem</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">isSelected</span><span
style=" color:#000000;">()</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">)</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;">{</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;">curLine</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curItem</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:#800080;">QStringList</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">curKeyValue</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curLine</span><span style=" color:#000000;">.</span><span
style=" color:#000000;">split</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">'\t'</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;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strUser</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">curKeyValue</span><span style=" color:#000000;">[</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:#800080;">QByteArray</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">baOldHash</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">m_mapUserAndHash</span><span style=" color:#000000;">[</span><span
style=" color:#000000;">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></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;">emit</span><span