-
Notifications
You must be signed in to change notification settings - Fork 7
/
ch08-01.htm
4110 lines (2808 loc) · 254 KB
/
ch08-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>ch08-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">8.1 列表控件</div>
<br>
之前第 7 章有多个示例都用到了列表控件,本节再详细介绍一下列表控件 QListWidget 和它的数据条目
QListWidgetItem,列表控件用于显示单列多行数据,而且可以用程序代码编写能够手动编辑的动态列表,列表的条目可以有图标,并有多种显示模式,本节会通过两
个示例学习列表控件丰富的功能。<br>
<br>
<div class="os2">8.1.1 QListWidget</div>
<br>
在 Qt 设计师,左边的控件工具箱可以看到本章三个基于条目控件:<br>
<center> <img src="images/ch08/ch08-01-01.png" alt="item-based widgets" width="800">
</center>
QListWidget 的基类是 QListView 视图类,关于基类的内容本节不介绍,等到模型视图章节再讲,本节只关注 QListWidget
本身的函数。<br>
QListWidget 的构造函数很简单:<br>
<div class="code">QListWidget(QWidget * parent = 0)</div>
parent 是父窗口指针,如果用设计师拖控件,一般也不用手动调用构造函数。QListWidget
主要的函数是围绕条目添加、删除、选中条目、显示模式等功能以及相关的信号和槽,下面大致对这些功能函数分类来讲解:<br>
(1)添加条目的函数<br>
<div class="code">void QListWidget::addItem(QListWidgetItem * item)</div>
这个添加函数需要实现 new 一个 QListWidgetItem 条目对象,然后添加到列表控件末尾,下面小节会专门讲 QListWidgetItem
类。<br>
<div class="code">void QListWidget::addItem(const QString & label)</div>
这第二个添加函数其实更常用,因为更简便,功能是将字符串 label 添加到列表控件末尾显示,其实该函数内部会自动根据字符串 new
一个条目对象添加到列表控件。<br>
如果有设置好的字符串列表,那么可以通过如下函数把多个字符串全部添加到列表控件:<br>
<div class="code">void QListWidget::addItems(const QStringList &
labels)</div>
<br>
add* 函数是将条目添加到末尾,如果要将条目插入到指定行 row 位置,则使用 insert* 函数:<br>
<div class="code">void QListWidget::insertItem(int row, QListWidgetItem *
item) //插入条目到第 row 行</div>
<div class="code">void QListWidget::insertItem(int row, const QString &
label) //插入字符串到第 row 行</div>
<div class="code">void QListWidget::insertItems(int row, const QStringList
& labels) //插入多个字符串到从 row 行开始的多个行</div>
<br>
获取列表控件里面的条目计数使用如下函数:<br>
<div class="code">int QListWidget::count() const</div>
<br>
(2)删除函数<br>
因为是基于条目的控件,所以列表控件的删除单个条目函数名字是 takeItem():<br>
<div class="code">QListWidgetItem * QListWidget::takeItem(int row)</div>
takeItem() 根据行号从列表控件移除一个条目,并返回该条目指针,如果行号不合法,返回 NULL 指针。<br>
如果返回的是实际存在的条目,那么需要注意,返回的条目指针需要手动 delete 掉,因为列表控件不再拥有该条目,该条目不会由列表控件析构时自动删除。<br>
takeItem() 函数还有第二个用途,因为列表控件没有直接的调整条目前后顺序的函数,可以先将要调整顺序的条目移出来
takeItem(),然后再调用 insertItem() 把这个条目插入到新的位置。<br>
<br>
如果要清空整个列表控件,删除之前添加的所有条目,可以调用槽函数:<br>
<div class="code">void QListWidget::clear()</div>
<br>
(3)条目访问函数<br>
根据行号获取条目对象的指针,使用如下函数:<br>
<div class="code">QListWidgetItem * QListWidget::item(int row) const</div>
如果已知列表控件含有的条目对象指针,反查当前行号,使用如下函数:<br>
<div class="code">int QListWidget::row(const QListWidgetItem * item) const</div>
<br>
在图形界面,如果希望根据列表控件在屏幕显示的相对坐标位置(以列表控件内部左上角为原点)来获取条目,使用如下函数:<br>
<div class="code">QListWidgetItem * QListWidget::itemAt(const QPoint &
p) const</div>
<div class="code">QListWidgetItem * QListWidget::itemAt(int x, int y) const</div>
反过来,如果根据已知条目,获取这个条目占据的矩形区域,使用如下函数:<br>
<div class="code">QRect QListWidget::visualItemRect(const QListWidgetItem *
item) const</div>
<br>
(4)当前选中条目的操作<br>
获取列表控件当前选中条目的函数如下:<br>
<div class="code">QListWidgetItem * QListWidget::currentItem() const //当前选中
条目</div>
<div class="code">int QListWidget::currentRow() const //当前选中的行号</div>
如果当前没有选中的条目,那么返回的指针为 NULL,返回的序号为 -1 ,代码里要注意判断返回值。<br>
<br>
设置已存在的某个条目为选中状态,使用函数:<br>
<div class="code"> void QListWidget::setCurrentItem(QListWidgetItem *
item) //设置当前选中条目为 item</div>
<div class="code">void QListWidget::setCurrentItem(QListWidgetItem * item,
QItemSelectionModel::SelectionFlags command)</div>
<div class="code">void QListWidget::setCurrentRow(int row,
QItemSelectionModel::SelectionFlags command)//设置当前选中行为 row</div>
<div class="code">void QListWidget::setCurrentItem(QListWidgetItem * item,
QItemSelectionModel::SelectionFlags command)</div>
第二个和第四个设置函数有个 SelectionFlags 类型的参数
command,这个参数决定选中的方式,是要选中QItemSelectionModel::Select ,还是取消选中
QItemSelectionModel::Deselect,还有其他选中方式,等到表格控件一节再详细列出来。<br>
如果当前选中的条目发生变化,会触发如下三个信号,可以根据实际用途选择合适的信号:<br>
<div class="code">void QListWidget::currentItemChanged(QListWidgetItem *
current, QListWidgetItem * previous)</div>
<div class="code">void QListWidget::currentRowChanged(int currentRow)</div>
<div class="code">void QListWidget::currentTextChanged(const QString &
currentText)</div>
注意参数里的指针有可能为空值,序号可能为 -1,字符串也可能是空串,一定要注意判断非法的参数值。<br>
<br>
本章的三个控件都可以设置选中模式,比如单选模式,一次只能选中一个条目,多选模式,一次可以选中多个条目等等,详细的选中模式在放到表格控件一节讲解,因为表格
中涉及的选中模式较多,一块讲解。本节的列表控件默认情况下,选中模式为单选 QAbstractItemView::SingleSelection,以上的
*current* 等函数都是基于默认的单选模式的。<br>
<br>
如果需要用到多选模式,可以设置 selectionMode 属性为
QAbstractItemView::ExtendedSelection,这种扩展选中模式类似常见的文件资源管理器的选中模式,可以使用 Ctrl 或
Shift 加鼠标点击实现多选:<br>
<div class="code">void setSelectionMode(QAbstractItemView::SelectionMode
mode) //设置选中模式</div>
<div class="code">QAbstractItemView::SelectionMode
selectionMode() const //获取选中模式</div>
QAbstractItemView 是本章所有控件的抽象基类,本章后面控件也有类似的选中模式设置,如果把列表控件设置成多选模式,那么可以用如下函数获取同
时选中的多个条目:<br>
<div class="code">QList<QListWidgetItem *>
QListWidget::selectedItems() const</div>
不论单选还是多选模式,条目选中情况有任何变化时,会触发如下信号:<br>
<div class="code">void QListWidget::itemSelectionChanged()</div>
<br>
(5)条目查找和排序<br>
如果需要根据文本查找匹配的条目,使用如下函数:<br>
<div class="code">QList<QListWidgetItem *>
QListWidget::findItems(const QString & text, Qt::MatchFlags flags)
const</div>
该函数第一个参数 text 是要查找的模板子串,第二个参数是匹配标志,Qt::MatchFlags
是非常通用的枚举类型,不仅可用于字符串匹配,还能用于其他类型变量的匹配,Qt::MatchFlags 包含关于查找匹配的多种方式的枚举值:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 200px;" align="center"><b>Qt::MatchFlags 枚举常量</b></td>
<td style="width: 200px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>Qt::MatchExactly</td>
<td> 0 </td>
<td> 精确匹配,执行基于 QVariant 的匹配。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchFixedString</td>
<td> 8 </td>
<td> 执行基于字符串的匹配,如果不指定 MatchCaseSensitive,默认是大小写不敏感。 </td>
</tr>
<tr>
<td>Qt::MatchContains</td>
<td> 1 </td>
<td> 条目包含要查找的模板子串。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchStartsWith</td>
<td> 2 </td>
<td> 条目以要查找的模板子串打头。 </td>
</tr>
<tr>
<td>Qt::MatchEndsWith</td>
<td> 3 </td>
<td> 条目以要查找的模板子串结尾。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchCaseSensitive</td>
<td> 16 </td>
<td> 查找时大小写敏感。 </td>
</tr>
<tr>
<td>Qt::MatchRegExp</td>
<td> 4 </td>
<td> 根据正则表达式模板子串匹配字符串。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchWildcard</td>
<td> 5 </td>
<td> 根据通配符模板子串(如 *.txt)匹配字符串。 </td>
</tr>
<tr>
<td>Qt::MatchWrap</td>
<td> 32 </td>
<td> 执行回绕查找,当查找到最后一个条目时返回到第一个的条目继续查找,直到所有的条目都检查一遍。 </td>
</tr>
<tr class="d1">
<td>Qt::MatchRecursive</td>
<td> 64 </td>
<td> 递归查找,遍历所有子条目。 </td>
</tr>
</tbody>
</table>
<br>
后面两节的表格控件和树形控件也有类似的查找函数 findItems() ,第二个匹配标志参数也是一样的类型。<br>
<br>
列表控件的自动排序是通过 sortingEnabled 属性来控制,获取和设置函数如下:<br>
<div class="code">bool isSortingEnabled() const</div>
<div class="code">void setSortingEnabled(bool enable)</div>
列表控件条目默认是不排序的,如果希望自动按照字典序排序,调用 setSortingEnabled(true) 即可。另外还可以手动对列表控件现有条目排
序:<br>
<div class="code">void QListWidget::sortItems(Qt::SortOrder order =
Qt::AscendingOrder)</div>
Qt::AscendingOrder 是按升序排列,Qt::DescendingOrder 是按降序排列。<br>
<br>
(6)条目显示和运行时条目编辑<br>
关于列表控件 QListWidget 和里面的条目 QListWidgetItem,需要注意条目 QListWidgetItem
仅仅是数据,不是控件或子控件,列表控件根据多个 QListWidgetItem 对象,来呈现条目里的数据,只有列表控件自己是控件实体。<br>
列表控件默认以自己的方式呈现条目数据,比如白底黑字的普通条目显示,如果要按照特殊的子控件来显示字符串,比如用 QLabel
对象显示条目数据,可以用如下函 数:<br>
<div class="code">void QListWidget::setItemWidget(QListWidgetItem * item,
QWidget * widget)</div>
列表控件会同时拥有 item 数据条目和用于显示 item 的子控件 widget。注意这里的子控件 widget
只有静态显示功能,如果用按钮作为显示子控件,那么按钮是不可点击的。如果希望自己定制一个能交互操作的子条目显示控件,需要使用
QListView 并子类化 QItemDelegate 类,这些复杂的等到模型视图章节再讲。<br>
<br>
对于本节列表控件,如果要获取 setItemWidget() 函数指定某个条目的显示子控件,使用如下函数:<br>
<div class="code">QWidget * QListWidget::itemWidget(QListWidgetItem * item)
const</div>
如果要删除上面 setItemWidget() 指定的特殊显示控件,使用函数:<br>
<div class="code">void QListWidget::removeItemWidget(QListWidgetItem *
item)</div>
特殊的显示子控件移除后,该条目就还按照列表控件原来的普通条目显示。<br>
<br>
如果希望在程序运行时编辑列表控件的条目,有两种方式,本小节先讲第一种(第二种是设置条目自身的特性标志),手动打开条目的文本编辑器(这个编辑器是列表控件自
带功能,与 setItemWidget 设置的显示子控件没关系):<br>
<div class="code">void QListWidget::openPersistentEditor(QListWidgetItem *
item)</div>
这个函数名是打开条目的持续编辑器,持续的意思是如果不调用关闭函数,该条目的编辑器会一直开启,关闭这个持续编辑器使用如下函数:<br>
<div class="code">void QListWidget::closePersistentEditor(QListWidgetItem *
item)</div>
一般可以在检测到条目激活信号(itemActivated)时调用打开函数 openPersistentEditor() ,在当前条目变化(
currentItemChanged)时调用关闭函数 closePersistentEditor() 。
使用这一对开关持续编辑器函数涉及到编写多个信号的槽函数,使用比较麻烦,建议用后面第二小节介绍的条目标 志位和
QListWidget::editItem(QListWidgetItem * item) 实现条目的可编辑功能。<br>
<br>
(7)其他信号和槽函数<br>
除了上面关于当前条目变化和选中条目变化的信号,条目还有激活、单击、双击等信号,罗列如下:<br>
<div class="code">void QListWidget::itemActivated(QListWidgetItem *
item) //激活信号</div>
当用户点击或双击条目时,条目会被激活,具体哪些操作会激活条目,要根据操作系统设置来定,比如 Windows 一般是双击打开激活,KDE
桌面通常是单击打开激活。另外,系统的快捷键也可以激活条目,如 Windows 和 Linux X11 桌面是回车键激活,Mac OS X 是
Ctrl+0 ,一般激活信号用于开启编辑等操作。<br>
<div class="code">void QListWidget::itemChanged(QListWidgetItem *
item) //条目内容发生变化</div>
注意这是条目内容变化的信号,不是选中状态变化,程序如果在运行时改变了条目文本内容,比如持续编辑器修改了文本,会触发这个信号。<br>
剩下几个单击、双击、进入、按压等信号意义比较直白,不详细解释了:<br>
<div class="code">void QListWidget::itemClicked(QListWidgetItem *
item) //条目单击信号</div>
<div class="code">void QListWidget::itemDoubleClicked(QListWidgetItem *
item) //条目双击信号</div>
<div class="code">void QListWidget::itemEntered(QListWidgetItem *
item) //鼠标追踪时进入条目的信号,一般用不着</div>
<div class="code">void QListWidget::itemPressed(QListWidgetItem *
item) //鼠标按键在条目上处于按下状态时发的信号</div>
<br>
列表控件的槽函数除了前面讲过的 clear()
槽函数用于清空所有条目,还有个比较实用的条目滚动函数,列表控件自带滚动条,当条目总数超出控件矩形能呈现的数目时,滚动条自动出现,通过滚动条支持更多的条目显示。使
用如下槽函数可 以让列表控件滚动到想显示的某个条目位置:<br>
<div class="code">void QListWidget::scrollToItem(const QListWidgetItem *
item, QAbstractItemView::ScrollHint hint = EnsureVisible)</div>
第一个参数 item 就是想显示出来的条目,第二个参数是滚动显示方式,默认是
QAbstractItemView::EnsureVisible,即保证指定条目显示出来,还有其他的滚动显示方式:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 360px;" align="center"><b>QAbstractItemView::
ScrollHint 枚举常量</b></td>
<td style="width: 140px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>QAbstractItemView::EnsureVisible</td>
<td> 0 </td>
<td> 滚动到指定条目能显示出来即可。 </td>
</tr>
<tr class="d1">
<td>QAbstractItemView::PositionAtTop</td>
<td> 1 </td>
<td> 滚动直到将指定条目显示到可视区域的顶部。 </td>
</tr>
<tr>
<td>QAbstractItemView::PositionAtBottom </td>
<td> 2 </td>
<td> 滚动直到将指定条目显示到可视区域的底部。 </td>
</tr>
<tr class="d1">
<td>QAbstractItemView::PositionAtCenter</td>
<td> 3 </td>
<td> 滚动直到将指定条目显示到可视区域的中间。 </td>
</tr>
</tbody>
</table>
<br>
关于列表控件的函数介绍这些,下面讲解与之配合使用的条目类 QListWidgetItem。<br>
<br>
<div class="os2">8.1.2 QListWidgetItem</div>
<br>
QListWidgetItem 专门用于表示列表控件 QListWidget 的数据条目,注意 QListWidgetItem
是一个纯数据类,不是控件,没有基类,也就没有信号和槽函数。QListWidgetItem 可以直接用数据流 QDataStream 读写。<br>
QListWidgetItem 不单单有字符串,还可以有自己的图标、复选框等特性,列表控件会根据条目对象的丰富特性来呈现数据并进行交互操作。<br>
(1)首先来看看列表控件条目的构造函数:<br>
<div class="code">QListWidgetItem(QListWidget * parent = 0, int type = Type)</div>
<div class="code">QListWidgetItem(const QString & text, QListWidget *
parent = 0, int type = Type)</div>
<div class="code">QListWidgetItem(const QIcon & icon, const QString
& text, QListWidget * parent = 0, int type = Type)</div>
那第三个构造函数的参数来讲,icon 是条目显示的图标,text 是条目文本,parent 是条目隶属的列表控件,type 是条目的自定义类型。<br>
如果在构造函数指定了条目隶属的列表控件,那么这个条目会自动添加到列表控件末尾,而不需要调用列表控件的 add*() 和 insert*()函数,比如:<br>
<div class="code"> new QListWidgetItem(tr("Hazel"),
listWidget);</div>
只需要上面一句代码,"Hazel" 条目就自动显示在列表控件 listWidget 里面了,只要指定所隶属的列表控件,新建的条目自动添加并显示在末尾。<br>
<br>
(2)条目的复制方式,有三个函数可以实现:<br>
<div class="code">QListWidgetItem(const QListWidgetItem & other)
//复制构造函数</div>
<div class="code">QListWidgetItem & operator=(const QListWidgetItem
& other) // = 赋值函数</div>
<div class="code">virtual QListWidgetItem * clone() const //克隆函数</div>
复制构造函数和 = 赋值函数 函数原理是一样的,它们除了 type() 和 listWidget()
函数指定的两个数据不复制,其他的数据都复制。type() 是条目的自定义类型,listWidget() 是该条目所隶属的列表控件。<br>
而克隆函数 clone() 会精确复制所有数据,如果原条目隶属某个列表控件,克隆出来的也会自动隶属该列表控件,自定义条目类型也一样。<br>
顺便说一下列表条目的比较函数:<br>
<div class="code">virtual bool operator<(const QListWidgetItem &
other) const</div>
只有一个小于号函数,是比较列表条目文本的字典序先后关系,没有等于号函数和大于号函数,如果确实用到条目文本比较,建议直接用 QString 变量进行比较。<br>
<br>
(3)QListWidgetItem 的功能函数与内部数据<br>
QListWidgetItem 绝大部分的功能函数都是围绕内部数据处理的,QListWidgetItem
内部的数据大致分为两类:第一类是以数据角色形式管理的通用数据,这些数据自动参与 QDataStream
数据流的读写;第二类是非通用数据,不参与数据流读写,与 QListWidgetItem 和 QListWidget 自身特性有关。<br>
<br>
● 第一类:QListWidgetItem 的通用数据<br>
通用数据是以数据角色与数据变量一一对应的形式存储管理,比如设置文本 setText()、设置图标 setIcon()
等函数,其本质都是根据各自的角色调用通用设置数据的函数:<br>
<div class="code">virtual void setData(int role, const QVariant & value)</div>
也可以根据角色来获取各个数据变量:<br>
<div class="code">virtual QVariant data(int role) const</div>
<br>
查看列表控件源码文件:<br>
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\widgets\itemviews\qlistwidget.h<br>
可以看到关于文本变量的函数 text() 和 setText() 源代码:<br>
<div class="code">inline QString text() const<br>
{ return data(Qt::DisplayRole).toString(); }</div>
<div class="code">inline void QListWidgetItem::setText(const QString
&atext)<br>
{ setData(Qt::DisplayRole, atext); }</div>
关于 QListWidgetItem 内部通用数据的获取和设置函数、数据角色列表如下:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 110px;" align="center"><b>获取函数</b></td>
<td style="width: 280px;" align="center"><b>设置函数</b></td>
<td style="width: 150px;" align="center"><b>数据角色</b></td>
<td align="center"><b> 描述 </b></td>
</tr>
<tr>
<td>text()</td>
<td> setText(const QString &text) </td>
<td> Qt::DisplayRole </td>
<td> 条目显示的文本。 </td>
</tr>
<tr class="d1">
<td>icon()</td>
<td> setIcon(const QIcon &icon) </td>
<td> Qt::DecorationRole </td>
<td> 条目显示的图标。 </td>
</tr>
<tr>
<td>statusTip()</td>
<td> setStatusTip(const QString &statusTip) </td>
<td> Qt::StatusTipRole </td>
<td> 如果主界面有状态栏,鼠标悬停在该条目上时显示该状态信息到状态栏。 </td>
</tr>
<tr class="d1">
<td>toolTip()</td>
<td> setToolTip(const QString &toolTip) </td>
<td> Qt::ToolTipRole </td>
<td> 鼠标悬停在该条目上时显示的工具提示信息。 </td>
</tr>
<tr>
<td>whatsThis()</td>
<td> setWhatsThis(const QString &whatsThis) </td>
<td> Qt::WhatsThisRole </td>
<td> 如果主界面窗口标题栏有?帮助按钮,点击帮助按钮再点击该条目会显示该帮助信息。 </td>
</tr>
<tr class="d1">
<td>font()</td>
<td> setFont(const QFont &font) </td>
<td> Qt::FontRole </td>
<td> 显示条目文本用的字体。 </td>
</tr>
<tr>
<td>textAlignment()</td>
<td> setTextAlignment(int alignment) </td>
<td> Qt::TextAlignmentRole </td>
<td> 文本的对齐方式。 </td>
</tr>
<tr class="d1">
<td>backgroundColor()</td>
<td> setBackgroundColor(const QColor &color)</td>
<td> Qt::BackgroundColorRole </td>
<td> 文本背景色。 </td>
</tr>
<tr>
<td>textColor()</td>
<td> setTextColor(const QColor &color)</td>
<td> Qt::TextColorRole </td>
<td> 文字颜色。 </td>
</tr>
<tr class="d1">
<td>background()</td>
<td> setBackground(const QBrush &brush) </td>
<td> Qt::BackgroundRole </td>
<td> 条目的背景画刷。 </td>
</tr>
<tr>
<td>foreground()</td>
<td> setForeground(const QBrush &brush) </td>
<td> Qt::ForegroundRole </td>
<td> 条目的前景画刷。 </td>
</tr>
<tr class="d1">
<td>checkState()</td>
<td> setCheckState(Qt::CheckState state)</td>
<td> Qt::CheckStateRole </td>
<td> 条目自带的复选框选中状态,可以是三态复选框。 </td>
</tr>
<tr>
<td>sizeHint()</td>
<td> setSizeHint(const QSize &size) </td>
<td> Qt::SizeHintRole </td>
<td> 条目显示的建议尺寸。 </td>
</tr>
</tbody>
</table>
<br>
QListWidgetItem 可以直接用数据流 QDataStream
读写,涉及到读写的内部数据就是上表所列举的以角色形式表述的数据,QListWidgetItem 通过两个外部全局运算符重载函数支持
QDataStream 数据流读写:<br>
<div class="code">QDataStream &operator<<(QDataStream &out,
const QListWidgetItem &item)</div>
<div class="code">QDataStream &operator>>(QDataStream &in,
QListWidgetItem &item)</div>
使用运算符的形式比较方便,当然也可以用 QListWidgetItem 内部的读写函数:<br>
<div class="code">void QListWidgetItem::read(QDataStream & in)</div>
<div class="code">void QListWidgetItem::write(QDataStream & out) const</div>
<br>
QListWidgetItem 内部采用私有的 QVector 向量存储通用数据的 role 和 value 对:<br>
<div class="code"><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QVector</span><span
style=" color:#000000;"><</span><span style=" color:#800080;">QWidgetItemData</span><span
style=" color:#000000;">></span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">values</span><span style=" color:#000000;">;</span></div>
条目通用数据的读写就是读写私有向量 values,其中 QWidgetItemData 内部包含 role 和 value 成员变量:<br>
<div class="code"><span style=" color:#808000;">class</span><span style=" color:#c0c0c0;">
</span><span style=" color:#800080;">QWidgetItemData</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:#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;">inline</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidgetItemData</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;">role</span><span style=" color:#000000;">(-</span><span
style=" color:#000080;">1</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:#808000;">inline</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidgetItemData</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">r</span><span style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QVariant</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">v</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;">role</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">r</span><span style=" color:#000000;">),</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">value</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">v</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:#808000;">int</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">role</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;">QVariant</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">value</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;">inline</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#808000;">bool</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">operator</span><span style=" color:#000000;">==(</span><span
style=" color:#808000;">const</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QWidgetItemData</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">&</span><span style=" color:#000000;">other</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#808000;">const</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">return</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">role</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">==</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">other</span><span
style=" color:#000000;">.</span><span style=" color:#800000;">role</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">&&</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800000;">value</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">==</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">other</span><span
style=" color:#000000;">.</span><span style=" color:#800000;">value</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>
在 8.2 节表格控件的单元格条目也是类似的私有向量存储 role 和 value 对。<br>
<br>
● 第二类:QListWidgetItem 的非通用数据<br>
条目自定义类型:<br>
<div class="code">int QListWidgetItem::type() const</div>
这个条目类型只能在构造函数指定,指定之后不能修改,默认值为 QListWidgetItem::Type (数值
0),如果程序员希望自己区分列表控件条目的类型,那么可以自己定义大于 QListWidgetItem::UserType (数值
1000)的类型值,一般用在 QListWidgetItem 派生类里面。<br>
<br>
条目所隶属的列表控件:<br>
<div class="code">QListWidget * QListWidgetItem::listWidget() const</div>
条目自身不能修改所隶属的列表控件,要通过列表控件的删除函数 QListWidget::takeItem(int row) 才能解除隶属关系。<br>
<br>
列表条目本身的选中状态(与复选框无关,是用户在列表控件点击条目的高亮选中状态):<br>
<div class="code">void QListWidgetItem::setSelected(bool select)</div>
<div class="code">bool QListWidgetItem::isSelected() const</div>
一般是用户在列表控件图形界面点击哪个条目,哪个条目就处于高亮选中状态,这里可以用条目自身的函数设置高亮选中状态。<br>
<br>
条目在列表控件里面显示或者隐藏:<br>
<div class="code">void QListWidgetItem::setHidden(bool hide)</div>
<div class="code">bool QListWidgetItem::isHidden() const</div>
<br>
条目的特性标志:<br>
<div class="code">void QListWidgetItem::setFlags(Qt::ItemFlags flags)</div>
<div class="code">Qt::ItemFlags QListWidgetItem::flags() const</div>
flags 会决定条目的工作特性,比如是否有三态复选框,是否在用户双击该条目时开启文本编辑器等等,Qt::ItemFlags 枚举值见下面表格:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 200px;" align="center"><b>Qt::ItemFlags 枚举常量</b></td>
<td style="width: 100px;" align="center"><b>数值</b></td>
<td align="center"><b> 描述</b></td>
</tr>
<tr>
<td>Qt::NoItemFlags</td>
<td> 0 </td>
<td> 不设置任何特性,条目会处于完全的不可用状态。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsSelectable</td>
<td> 1 </td>
<td> 条目本身可以被高亮选中。 </td>
</tr>
<tr>
<td>Qt::ItemIsEditable </td>
<td> 2 </td>
<td> 条目可以被编辑,比如用户双击条目时自动启用文本编辑器。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsDragEnabled</td>
<td> 4 </td>
<td> 条目可以被拖拽出去。 </td>
</tr>
<tr>
<td>Qt::ItemIsDropEnabled </td>
<td> 8 </td>
<td> 条目可以作为拖拽的目的地。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsUserCheckable</td>
<td> 16 </td>
<td> 条目可以有复选框,用户能勾选复选框。 </td>
</tr>
<tr>
<td>Qt::ItemIsEnabled </td>
<td> 32</td>
<td> 条目处于可用状态。 </td>
</tr>
<tr class="d1">
<td>Qt::ItemIsTristate</td>
<td> 64 </td>
<td> 条目的复选框可以有三种勾选状态:选中、非选中、部分选中。 </td>
</tr>
<tr>
<td>Qt::ItemNeverHasChildren </td>
<td> 128 </td>
<td> 条目不能有子条目(指树形控件)。 </td>
</tr>
</tbody>
</table>
<br>
上表中的 Qt::ItemFlags 也适用于后面 8.2 节的表格控件条目和 8.3
节的树形控件条目,表格条目和树形条目也都有一样的条目标志位设置函数,功能与本节列表条目一样,参数也一样。<br>
列表控件条目默认的特性标志为同时启用四个:<br>
Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
Qt::ItemIsDragEnabled<br>
<br>
按照默认标志位,列表条目是可以有复选框进行勾选的,调用 QListWidgetItem::setCheckState()
函数可以让列表条目的复选框显示出来。<br>
如果要设置三态复选框,可以使用下面的代码:<br>
<div class="code"><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">setFlags</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsTristate</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span><span
style=" color:#c0c0c0;"> </span><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:#c0c0c0;"> </span><span style=" color:#000000;">item</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setCheckState</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">Unchecked</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//显示复选框</span></pre>
</div>
如果希望用户在双击条目时,自动开启条目文本的编辑器,可以用下面代码:<br>
<div class="code"><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">setFlags</span><span style=" color:#000000;">(</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">Qt</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsEditable</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">);</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//双击条目会自动
开启文本编辑器</span></div>
因为可以设置条目的 Qt::ItemIsEditable 标志位,所以列表控件 QListWidget 的一对持续编辑器函数
openPersistentEditor() 和 closePersistentEditor()
一般不需要手动调用,直接设置条目自身的可编辑标志位就行了。<br>
对于启用可编辑标志位的条目,如果希望通过代码开启条目的编辑,可以调用列表控件的 editItem()
函数来实现,而不需要使用一对开关持续编辑器函数那么麻烦:<br>
<div class="code">void QListWidget::editItem(QListWidgetItem * item)</div>
<br>
这里说明一下:<span style="font-weight: bold;">列表条目本身是可以存储复选框的勾选状态数值,而条目显示的复选框是由列表控
件绘制并提供,列表条目自身不是控件,也不包含子控件。类似地,列表控件根据 Qt::ItemIsEditable
标志位检查是否需要为条目提供文本编辑器</span>。<br>
<br>
在 QtCreator 设计模式和 Qt 设计师界面,都可以直接编辑列表控件、表格控件、树形控件的条目,右击这些控件,在右键菜单选择“编辑项目 ...”
菜单项即可,上面提到的条目数据,不管是通用的还是非通用的,只要可以修改,几乎都能在图形设计界面可视化编辑,等会例子中再示范。后面 8.2 节表格控件和
8.3
节的树形控件的条目有很多与列表控件类似的数据格式、接口函数、特性标志等,本节的表格关于函数和常量的枚举表格在后面两节都有用到,很多内容是一样的。关于列表控件和条
目的内容介绍到这,下面看看例子。<br>
<br>
<div class="os2">8.1.3 游戏装备列表示例</div>
<br>
在 7.1.5
文件系统浏览示例,我们就已经使用到列表控件了,并且条目既有图标也有文本显示,读者可以复习一下前面的示例。本小节示例是一个可编辑的游戏装备列表,学习
QtCreator 设计模式和 Qt 设计师里面列表控件的可视化编辑,而程序运行时也可以自己选择装备图标、设置游戏装备名称,并支持条目数据的保存和加载。<br>
在开始例子之前,先下载一个游戏装备图标压缩包: <br>
<a href="https://lug.ustc.edu.cn/sites/qtguide/QtProjects/ch08/dotaitems/dotasytb.zip"
target="new">
https://lug.ustc.edu.cn/sites/qtguide/QtProjects/ch08/dotaitems/dotasytb.zip
</a> <br>
压缩包解压之后,有个 DOTA-ITEM
文件夹,里面是游戏装备图标,我们抽取蝴蝶(fgfh.jpg)、金箍棒(odef.jpg)、大炮(rman.jpg)
三个图标备用,例子内嵌资源使用这三个图标,然后我们开始这个例子的学习。<br>
打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 dotaitems,创建路径 D:\QtProjects\ch08,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
<br>
在开始图形界面编辑之前,我们先添加图标和资源文件:<br>
在源码文件夹 D:\QtProjects\ch08\dotaitems 里新建一个叫 icons 的子文件夹,然后把三个图标文件
fgfh.jpg、odef.jpg、rman.jpg 放到 icons 子文件夹。<br>
然后在 QtCreator 左边项目管理面板,右击 dotaitems 项目名称,右键菜单选中 "添加新文件" ,弹出新建文件对话框,<br>
<center><img src="images/ch08/ch08-01-02.png" alt="rc1" width="800"></center>
选择新建 Qt Resource File,点击 "Choose..." 按钮,进入如下界面,<br>
<center><img src="images/ch08/ch08-01-03.png" alt="rc2" width="800"></center>
名称填写 icons,路径用当前项目文件夹,点击 "下一步",<br>
<center><img src="images/ch08/ch08-01-04.png" alt="rc3" width="800"></center>
项目管理界面不用修改,点击完成。进入 QtCreator 资源文件编辑界面,我们在左边项目管理面板右击 icons.qrc 文件名,<br>
<center><img src="images/ch08/ch08-01-05.png" alt="rc4" width="800"></center>
右键菜单选择 "添加现有文件",在弹出的文件对话框,选择 icons 子文件夹里三个图标文件添加,添加好之后如下图所示:<br>
<center><img src="images/ch08/ch08-01-06.png" alt="rc5" width="800"></center>
这样图标和资源文件就编辑好了,保存该资源文件,关闭该文件。接下来我们编辑 ui 界面文件。<br>
<br>
我们打开 widget.ui 界面文件,按照下图拖入控件:<br>
<center><img src="images/ch08/ch08-01-07.png" alt="ui" width="800"></center>
界面分为左边和右边两个大部分:<br>
左边上方是列表控件,对象名为 listWidget;左下是单行编辑器,对象名为 lineEditToolTip,左边两个控件按照垂直布局排布。<br>
右边是六个按钮,第一个按钮文本是 "添加",对象名 pushButtonAdd;第二个按钮文本是 "删除",对象名
pushButtonDel;第三个按钮文本是 "切换显示模式",对象名 pushButtonViewMode;第四个按钮文本为 "加载",对象名
pushButtonLoad;第五个按钮文本为 "保存",对象名为 pushButtonSave;在 "保存"
按钮下面是一个垂直的空白条,用默认的对象名即可;第六个按钮文本为 "编辑工具提示",对象名为
pushButtonEditToolTip。右边的控件也是按照垂直布局器排布,主界面是按照水平布局器排布。<br>
<br>
这里解释一下这些控件的用途:<br>
列表控件显示游戏装备的图标和名称列表,初始时显示资源文件内嵌的三个游戏装备;<br>
"添加" 按钮可以从磁盘添加新的游戏装备图标和装备名;"删除" 按钮是从列表删除一个条目;<br>
"切换显示模式" 按钮用于控制列表控件的显示方式,是小图标文字模式,还是大图标模式;<br>
"保存" 按钮是将当前列表控件条目保存为自定义的 *.item 数据流文件,"加载" 按钮是加载之前存的文件;<br>
单行编辑器和 "编辑工具提示" 按钮,是设置列表当前选中条目的工具提示信息,相当于游戏装备描述信息。<br>
<br>
我们现在来学一下让列表控件初始时显示三个装备条目,在 QtCreator 和 Qt 设计师里面,可以直接为列表控件、表格控件、树形控件(都是
Item-Based)添加条目,这些条目可以自动在程序启动时显示。我们右击列表控件,在右键菜单看到 "编辑项目..." 菜单项:<br>
<center><img src="images/ch08/ch08-01-08.png" alt="item1" width="800"></center>
"编辑项目..." 这个菜单项的用途就是编辑条目的意思,点击之后看到如下条目编辑对话框:<br>
<center><img src="images/ch08/ch08-01-09.png" alt="item2"></center>
绿色加号图标按钮就是添加新的条目,我们添加三个条目,条目文本为 "蝴蝶"、"金箍棒"、"大炮" :<br>
<center><img src="images/ch08/ch08-01-10.png" alt="item3"></center>
条目不仅有文字,还可以编辑条目的 "属性",就是上面小节介绍的 QListWidgetItem 通用数据和非通用数据,点击 "属性"
按钮,可以看到条目的详细编辑内容:<br>
<center><img src="images/ch08/ch08-01-11.png" alt="item4"></center>
对于第一个条目 "蝴蝶" ,我们点击属性 icon,再点击 icon 右边一栏的小按钮,在菜单里点击 "选择资源" :<br>
<center><img src="images/ch08/ch08-01-12.png" alt="item5"></center>
然后我们选择蝴蝶的图标给该条目:<br>
<center><img src="images/ch08/ch08-01-13.png" alt="item6"></center>
添加之后,可以看到第一个条目有蝴蝶图标了:<br>
<center><img src="images/ch08/ch08-01-14.png" alt="item7"></center>
然后我们编辑蝴蝶条目的 toolTip ,可以自己在网上找点蝴蝶的描述信息填到该工具提示里面:<br>
<center><img src="images/ch08/ch08-01-15.png" alt="item8"></center>
上图设置的就是HTML丰富文本的工具提示信息,原本是从网页复制到 "多文本" 编辑模式里的,如果点击 "源" 编辑模式,可以看到 HTML 的源码:<br>
<div class="code"><html><head/><body><p><span
style=" font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;">+30点攻击力<br/>+30%攻速<br/>+30点敏
捷<br/></span><span style="
font-family:'宋体,arial,sans-serif'; font-size:12px; color:#66ffff;
background-color:#121212;">+35%的物理攻击闪避</span></p><
/body></html></div>
编辑后点击确定,回到条目编辑界面,关于蝴蝶条目,还有其他的数据信息可以编辑,读者可以自己试试看,上文提到的条目数据几乎都可以在右边的属性编辑栏里面找到。<br>
<br>
然后我们如法炮制,为列表控件第二个、第三个条目添加图标和工具提示:<br>
<center><img src="images/ch08/ch08-01-16.png" alt="item9"></center>
<br>
金箍棒的描述信息也是丰富文本,HTML源码如下:
<div class="code"><html><head/><body><p><span
style=" font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;">+88点攻击力<br/>+15%攻速<br/><
/span><span style=" font-family:'宋体,arial,sans-serif';
font-size:12px; color:#66ffff;
background-color:#121212;">被动:攻击不会落空(与某些法球冲突,可关闭该效果),攻击中有35%的机率造成0.01秒的晕眩并
且+100点附加伤害</span></p></body></html></div>
大炮的描述信息 HTML 源码如下:
<div class="code"><html><head/><body><p><span
style=" font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;">+81点攻击力<br/>25%机率造成2.4倍伤害<br
/></span><span style=" font-family:'宋体,arial,sans-serif';
font-size:12px; color:#ffff00;
background-color:#121212;">通俗称呼:大炮</span></p></body><
/html></div>
这些描述信息是从如下网站复制的,可以直接粘贴到丰富文本编辑对话框里面(在多文本模式粘贴):<br>
<a href="http://db.pcgames.com.cn/dota/item_864.html" target="new">
http://db.pcgames.com.cn/dota/item_864.html </a> <br>
<br>
由于支持丰富文本的工具提示,Qt
的其他控件或控件条目可以展示非常棒的工具提示效果,不仅仅是丰富文本,我们还可以为工具提示添加资源里的图片,以第三个大炮的工 具提示编辑框为例:<br>
<center><img src="images/ch08/ch08-01-17.png" alt="item10"></center>
我们在多文本编辑模式,先在文字前按回车键,在文字之前新加空白行,然后点击上面 "插入图像" 按钮,看到选择资源图片的对话框:<br>
<center><img src="images/ch08/ch08-01-18.png" alt="item11"></center>
我们选中第三个大炮的图片添加到工具提示里面,可以看到如下效果:<br>
<center><img src="images/ch08/ch08-01-19.png" alt="item12"></center>
这是大炮的工具提示信息预览,等程序编译运行后我们再看看实际效果。<br>
在工具提示添加大炮图片之后,可以看看工具提示 HTML 源码的变化:<br>
<div class="code"><html><head/><body><p><img
src=":/icons/rman.jpg"/></p><p><span style="
font-family:'宋体,arial,sans-serif'; font-size:12px; color:#0090ff;
background-color:#121212;">+81点攻击力<br/>25%机率造成2.4倍伤害<br/><
/span><span style=" font-family:'宋体,arial,sans-serif';
font-size:12px; color:#ffff00;
background-color:#121212;">通俗称呼:大炮</span></p></body><
/html></div>
Qt编程中,一般支持丰富文本的控件或条目,都可以显示内嵌资源文件里的图片,内嵌资源里的图片供 HTML 引用的方式如下:<br>
<div class="code"><img src=":/icons/rman.jpg"/></div>
除了以冒号打头的图片路径,其他与标准的 HTML 图片引用没区别。<br>
<br>
关于条目属性编辑的内容还有很多:<br>
<center><img src="images/ch08/ch08-01-20.png" alt="item13"></center>
除了条目的文本、图标、工具提示,还可以设置状态栏信息、帮助信息、字体、文本对齐、背景色、前景色、条目特性标志以及复选框勾选状态等等。无论是通过
QtCreator 设计模式或 Qt 设计师的可视化编辑设置条目,还是通过编写代码调整条目的数据,都是可行的,等会我们再学习一些关于设置条目数据的代码。<br>
关于列表控件条目的可视化编辑就介绍这些,读者可以自己试试,尤其是条目的特性标志,可以把条目设置为可编辑的 Editable
标志,等会我们通过代码来修改。<br>
<br>
编辑好列表控件的条目之后,我们回到原来的界面编辑,为各个控件添加槽函数。<br>
右击列表控件,在右键菜单选择 "转到槽..." ,添加 currentItemChanged(QListWidgetItem *,
QListWidgetItem *) 信号对应的槽函数:<br>
<center><img src="images/ch08/ch08-01-21.png" alt="slot1"></center>
然后再类似操作一遍,还是为列表控件添加槽函数,再添加 itemChanged(QListWidgetItem * )
信号对应的槽函数。列表控件对应的两个槽函数功能等会再详解。<br>
<br>
主界面右边还有六个按钮控件,为每个按钮都添加 clicked() 信号对应的槽函数:<br>
<center><img src="images/ch08/ch08-01-22.png" alt="slot3"></center>
槽函数添加完成后,保存界面文件,关闭界面文件,回到 QtCreator 代码编辑模式,开始编写例子的代码。<br>
<br>
我们首先编辑头文件 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=" 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><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;"><QListWidgetItem></span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//列表控件条目</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_listWidget_currentItemChanged</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>current<span
style=" color:#000000;">,</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>previous<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_listWidget_itemChanged</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span>item<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_pushButtonAdd_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_pushButtonDel_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_pushButtonViewMode_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_pushButtonLoad_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_pushButtonSave_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_pushButtonEditToolTip_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:#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>
列表控件对应的槽函数在头文件声明中用到了列表条目,所以提前包含了 <QListWidget> 和
<QListWidgetItem> 两个类头文件,其他的代码都是自动生成的,不用修改。<br>
下面编辑源文件 widget.cpp ,添加实际的功能代码,这个文件代码比较多,我们逐个函数来看。<br>
首先是头文件包含和构造函数代码:<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;"><QIcon></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;"><QFileDialog></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;"><QMessageBox></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;"><QFile></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;"><QDataStream></span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//数据流,加载和保存条目数据</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=" 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;">ui</span><span style=" color:#000000;">-></span><span
style=" color:#800000;">listWidget</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:#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;">QListWidgetItem</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">item</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;">listWidget</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">item</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:#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;">item</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setFlags</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">(</span><span
style=" color:#000000;">item</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">flags</span><span style=" color:#000000;">())</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">|</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Qt</span><span style=" color:#000000;">::</span><span style=" color:#800080;">ItemIsEditable</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;">item</span><span