-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathch05-05.htm
More file actions
2610 lines (1845 loc) · 169 KB
/
Copy pathch05-05.htm
File metadata and controls
2610 lines (1845 loc) · 169 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>ch05-05</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 style=" background-color: white;">
<div class="os1">5.5 显示类的控件 </div>
<br>
本节显示类控件是指作为显示用途的控件,本节先对 Qt 设计师里面的显示类控件做个简要介绍,然后详细讲解 QLabel
的功能,因为标签控件是最常用到的。显示类的控件有简单的,也有很复杂的,例子代码是展示简单显示控件的用途,本节有两个示例,一个是用标签控件显示图片的例子,第二个是
电子钟的例子。 <br>
<br>
<div class="os2">5.5.1 显示控件概览</div>
<br>
在 Qt 设计师左边控件列表里可以看到如下图所示的显示控件:<br>
<center><img src="images/ch05/ch05-05-01.png" alt="display"></center>
下面概括介绍图上标出的各个显示控件:<br>
(1)标签控件 QLabel<br>
标签控件毫无疑问是最常用的,本教程第二章都是拿标签控件作为显示的例子,但之前只是用,没有全面地介绍这个控件类,我们在后面 5.5.2 节专门讲
QLabel。<br>
<br>
(2)丰富文本浏览控件 QTextBrowser<br>
QTextBrowser 就是 QTextEdit 的只读版本,并且添加了额外的浏览器的功能,这个类在 5.3.3 节已经讲过了。<br>
<br>
(3)图形视图 QGraphicsView<br>
这是专门用于绘制图形的视图类,它的内部工作原理也是遵循 View/Modal 框架的,QGraphicsView 类是属于视图显示的部分,而内部模型是
QGraphicsScene,绘图场景类内部可以添加各种图形,如线条、矩形、多边形,另外还可以自定义绘图条目
QGraphicsItem,本教程有图形图像专题,等到该专题的章节再详细介绍。<br>
<br>
(4)日历控件 QCalendarWidget<br>
前面 5.4 节讲过日期编辑器有自动弹出日历的功能,弹出的其实就是 QCalendarWidget 日历控件,QCalendarWidget
一般只用于日历显示。日历控件常用的属性是 selectedDate,就是选中的高亮的日子,该属性访问函数为:<br>
<div class="code">QDate selectedDate() const</div>
<div class="code">void setSelectedDate(const QDate & date)</div>
用户是可以从日历界面自己选中日子的,选中日子变化时,发送信号:<br>
<div class="code">void selectionChanged()</div>
日历控件默认是不显示日子列表的网格,可以通过属性 gridVisible 改变是否显示网格的特性,访问函数为:<br>
<div class="code">bool isGridVisible() const</div>
<div class="code">void setGridVisible(bool show)</div>
日历控件因为有一个月的日子列表,比较占界面的空间,如果涉及到日子编辑,建议用日期编辑器,日期编辑器也是可以弹出日历的,日期编辑器占的地方也比较小。<br>
<br>
(5)LCD 数字显示 QLCDNumber<br>
这里的 LCD 数字显示控件就是比较传统的电子表、计算器等液晶显示器,也俗称 888 显示器,每个数字都是通过部分 8
的笔画来显示。QLCDNumber 的属性及设置函数、描述如下表所示:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 140px;" align="center"><b>属性</b></td>
<td style="width: 280px;" align="center"><b>设置函数</b></td>
<td align="center"><b>描述</b></td>
</tr>
<tr>
<td><b>digitCount</b></td>
<td>void setDigitCount(int)</td>
<td>数字的位数限定,这个控件类不限定数值大小,只限定数的位数。</td>
</tr>
<tr class="d1">
<td><b>segmentStyle</b></td>
<td style="height: 30px;">void setSegmentStyle(SegmentStyle)</td>
<td>设置笔画线段的显示风格。SegmentStyle 是枚举类型,有三种,默认是QLCDNumber::Filled </td>
</tr>
<tr>
<td><b>intValue 和<br>
value </b></td>
<td>void display(int num) <br>
void display(double num)<br>
void display(const QString & s) </td>
<td> 既可以获取整型数值 intValue(),也可以获取浮点数值 value()。数值的设置函数不叫 set*,而是
display() 函数。 </td>
</tr>
<tr class="d1">
<td><b>smallDecimalPoint</b></td>
<td> void setSmallDecimalPoint(bool) </td>
<td> 小数点的显示方式,默认情况下该属性为 false,小数点会占一个数字位。如果设置函数参数为
true,小型小数点就显示在数字之间的缝隙,而不会单独占一位。 </td>
</tr>
<tr>
<td><b>mode</b></td>
<td> void setMode(Mode) </td>
<td> 设置显示的数字类型,比如十进制、二进制等,默认是十进制 QLCDNumber::Dec。 </td>
</tr>
</tbody>
</table>
<br>
关于上面属性表格,再说明一下,属性的设置函数上面列举了,而属性的获取函数与属性名一样,所以没列。<br>
<br>
setSegmentStyle() 函数用于设置数字笔画的显示风格,显示风格 SegmentStyle 有三个枚举常量:<br>
①QLCDNumber::Outline,用背景色绘制笔画,这个显示风格其实看不清数字,不建议用。<br>
②QLCDNumber::Filled,用背景色填充每个笔画的边框,笔画内部用前景色绘制。在控件比较小时,每个数字位也比较小,笔画比较细,这个显示风格就
看不清数字,因为几乎全是用背景色画笔画。如果控件比较大,那么前景色绘制的部分就比较清晰。如果控件比较小,也不建议用这个风格。<br>
③QLCDNumber::Flat,笔画全部用前景色填充,笔画的边框也是一样的前景色,所以称为扁平风格,这个显示风格最推荐使用,笔画非常清晰。<br>
<br>
LCD 数字显示控件的数值,有两个属性,intValue 是整数类型,value
是双精度浮点数类型,这个控件类不限定数值的大小,只限定显示的数字位数。因为是数字显示控件,不是编辑控件,它的显示通过三个 display()
函数设置,使用 QString 为参数的 display() 函数,除了显示数字和小数点,还能显示一些能支持的字符,比如
字母O/数字0、S/5、g/9、负号、小数点、十六进制数、冒号、度数(°)等。<br>
<br>
LCD 数字显示控件的工作模式 mode 有四种,QLCDNumber::Hex 是十六进制、QLCDNumber::Dec
是十进制、QLCDNumber::Oct 是八进制、QLCDNumber::Bin 是二进制,默认的模式是十进制的。QLCDNumber
的功能基本围绕以上属性展开,弄清楚属性之后,使用该类控件就比较简单了。<br>
<br>
(6)进度条 QProgressBar<br>
进度条在文件的网络上传和下载过程中经常见到,因为某一个事情比较耗费时间,需要用进度条显示该事件完成的进度,一般显示进度的百分比,比如 78% 。进度条
QProgressBar 常用的属性、设置函数和描述如下表(不常用的略过了,详细情况可以查看帮助文档):<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 140px;" align="center"><b>属性</b></td>
<td style="width: 280px;" align="center"><b>设置函数</b></td>
<td align="center"><b>描述</b></td>
</tr>
<tr>
<td><b>orientation</b></td>
<td>void setOrientation(Qt::Orientation)</td>
<td>显示的方向,Qt::Horizontal 是水平进度条(默认值),Qt::Vertical 是垂直进度条。</td>
</tr>
<tr class="d1">
<td><b>format</b></td>
<td style="height: 30px;">void setFormat(const QString & format)</td>
<td>设置显示文本的格式,默认格式是 "%p%",就是百分比显示,如 78% </td>
</tr>
<tr>
<td><b>textVisible</b></td>
<td>void setTextVisible(bool visible) </td>
<td> 决定是否显示百分比的文本,一般是显示的,例外的是苹果系统风格从不显示进度条文本的。 </td>
</tr>
<tr class="d1">
<td><b>maximum</b></td>
<td>void setMaximum(int maximum)</td>
<td> 进度条数值的上限。</td>
</tr>
<tr>
<td><b>minimum</b></td>
<td>void setMinimum(int minimum)</td>
<td> 进度条数值的下限。 </td>
</tr>
<tr class="d1">
<td><b>value</b></td>
<td>void setValue(int value)</td>
<td> 进度条当前数值。</td>
</tr>
<tr>
<td><b>text</b></td>
<td>无</td>
<td> 进度条文本通过 format 属性设置,可以获取文本 text(),但不能直接设置文本。 </td>
</tr>
</tbody>
</table>
<br>
首先要明确的是进度条的数值设置,默认下限是 0,默认上限是 100,这样当数值 value 为 24 时,显示的文本就是 %24
,通过下限、上限、当前数值来计算需要显示的百分比文本,而不能直接设置显示的文本。<br>
数值的范围由 setMaximum() 和 setMinimum() 函数限定,或者用如下范围设置函数一次设置:<br>
<div class="code">void setRange(int minimum, int maximum)</div>
<br>
显示的文本格式通过 setFormat() 函数来控制,参数字符串默认是 "%p%" ,意义为:<br>
第一个 "%p" 是格式串占位符,指计算百分比数值,第二个 "%" 就是指百分号本身,这样显示的就是如 "24%" 字样。<br>
如果希望显示当前数值本身,而不是百分比,那么用格式串占位符 "%v" ,就代表当前的 value 值。<br>
另外还有一个格式串占位符是 "%m" ,代表上限减去下限的差额。<br>
<br>
三个格式串占位符是可以混搭的,比如 "%v/%m" 就是既显示当前值,也显示总差额,比如显示为 "24/100" 。<br>
除去三个占位符的其他字符,会照原样显示,比如 / 字符。再比如 "%v MB/%m MB",实际显示为 "24 MB/100 MB" 。<br>
<br>
默认是显示文本的,调用函数 setTextVisible(false) 就会不显示文本,只显示进度条本身。<br>
orientation 属性决定进度条的显示方向,水平进度条最为常见,对于垂直进度条的文本显示,有个例外的属性 textDirection,这个
textDirection 只对垂直进度条有效,表示垂直进度条的文本显示方向,其设置函数为 <br>
<div class="code">void setTextDirection(QProgressBar::Direction
textDirection) </div>
QProgressBar::TopToBottom 表示从顶部到底部显示文本,QProgressBar::BottomToTop
是从底部到顶部显示文本。<br>
<br>
(7)线条 Line<br>
线条控件就是纯粹作为分隔用途的,比如有多个用途的控件,可以用线条 Line 分隔一下。<br>
水平线条和垂直线条的类虽然在设计师里显示的类名叫 Line,实际上没有这个 Line 类。<br>
线条其实是用 QFrame 类模拟实现的,水平线条代码举例如下:<br>
<div class="code"> line = new QFrame(Form); <br>
line->setObjectName(QStringLiteral("line")); <br>
line->setGeometry(QRect(60, 60, 118, 3)); <br>
line->setFrameShape(QFrame::HLine); <br>
line->setFrameShadow(QFrame::Sunken); </div>
参数里的 Form 是父窗口指针,QFrame::HLine 就是画水平线条,QFrame::Sunken 是指绘制一个凹下去效果的三维阴影。<br>
垂直线条的代码举例如下:<br>
<div class="code">line_2 = new QFrame(Form); <br>
line_2->setObjectName(QStringLiteral("line_2")); <br>
line_2->setGeometry(QRect(70, 100, 3, 61)); <br>
line_2->setFrameShape(QFrame::VLine); <br>
line_2->setFrameShadow(QFrame::Sunken);</div>
水平线条和垂直线条属性 orientation 的取值不一样,Horizontal 是水平线条,Vertical 是垂直线条,其他都是类似的。Qt
设计师会根据线条的方向、位置、粗细,计算出线条占用的矩形,然后设置给 QFrame 对象。<br>
QFrame 是专门用于绘制边框的类,一般有边框特效的控件就是从 QFrame 派生的,本节标签控件、进度条控件、LCD 数字显示控件 的基类就是
QFrame。<br>
<br>
(8)OpenGL 三维绘图控件 QOpenGLWidget<br>
QOpenGLWidget 这个控件非常新,是从 Qt 5.4 版本才开始有的,这个控件用于在普通窗体里面进行 OpenGL
绘图。本教程有专门的图形图像专题,等到该专题的 OpenGL 3D 绘图章节再介绍这个控件。<br>
<br>
(9)QtQuick 1 控件 QDeclarativeView<br>
这个控件是从 Qt 4 保留而来的,目前 QtQuick 1 已经弃用了,所以不建议用这个控件了。在 Qt 设计师独立程序能看到这个控件,而在
QtCreator 设计模式已经没有这个控件了。<br>
<br>
(10)QtQuick 2 控件 QQuickWidget<br>
QQuickWidget 是 QtQuick 2 集成到普通窗体程序里的控件,是目前建议使用的控件。因为本教程暂时没有打算编写 QtQuick 2 和
QML 相关内容,所以也不讲这个控件。关于这个控件的使用方法请参考 QQuickWidget 帮助文档。<br>
<br>
(11)网页浏览视图 QWebView<br>
之前介绍过 QTextBrowser 是一个不完全的浏览器,而 QWebView 则是一个完整的浏览器控件,支持 HTML
全部特性,当然也有网络访问功能。QWebView 位于 Qt 的 webkitwidgets 模块里,使用该控件需要添加该模块到 *.pro
文件里面。在 Qt 5 之后,网页浏览相关的控件和类都基于 Chrome 核心了,所以效率是比较高的。在本教程的网络专题里面,专门讲这个浏览器控件。<br>
<br>
<div class="os2">5.5.2 QLabel 类</div>
<br>
之前用过很多次标签控件,比如显示丰富文本,利用 Qt Style Sheet 设置前景色、背景色,为伙伴控件设置快捷键等等,这里系统地把 QLabel
类讲解一下。<br>
QLabel 主要用于显示文本和图片,图片既可以是静态的 BMP、JPG、PNG 等,也可以是动态图格式如
GIF、MNG。标签控件是单纯用于显示的,没有编辑文本等用户交互功能,它的基类是 QFrame,意味着可以设置丰富的控件边框。<br>
QLabel 的构造函数有两个:<br>
<div class="code">QLabel(QWidget * parent = 0, Qt::WindowFlags f = 0)</div>
<div class="code">QLabel(const QString & text, QWidget * parent = 0,
Qt::WindowFlags f = 0)</div>
parent 是父窗口指针,f 是标签控件的窗口标志位,在 Qt 帮助文档关于 QLabel 构造函数详细内容里,可以点击
Qt::WindowFlags 链接,有很多的窗口标志位,对应不同的显示效果和功能,具体参考相应的帮助文档,这里不列举了。<br>
第二个构造函数的 text 就是显示的文本字符串。<br>
<br>
QLabel 可显示的内容是很丰富的,下表是从 Qt 帮助文档取出来并翻译的,展示了各种内容的设置函数:<br>
<br>
<table class="tabel">
<tbody>
<tr class="d1">
<td style="width: 140px;" align="center"><b>内容</b></td>
<td align="center"><b>设置方法</b></td>
</tr>
<tr>
<td><b>普通文本</b></td>
<td>传递 QString 字符串给 setText() 函数。</td>
</tr>
<tr class="d1">
<td><b>丰富文本</b></td>
<td>传递含有 HTML 标记的 QString 字符串给 setText() 函数。</td>
</tr>
<tr>
<td><b>像素图</b></td>
<td>传递一个 QPixmap 对象给 setPixmap() 函数。</td>
</tr>
<tr class="d1">
<td><b>短片</b></td>
<td>传递一个 QMovie 对象给 setMovie() 函数,QMovie 仅支持动态图,不是真的电影。</td>
</tr>
<tr>
<td><b>数字</b></td>
<td>传递一个 int 或 double 变量给 setNum() 函数,会显示普通的数字字符串。</td>
</tr>
<tr class="d1">
<td><b>无</b></td>
<td>等同于设置一个空字符串,也可以用函数 clear() 清空所有内容。</td>
</tr>
</tbody>
</table>
<br>
(1)文本设置<br>
首先从文本相关的函数开始,setText() 函数根据参数里的 QString 字符串内容,自动判断有没有 HTML 标记,如果是
HTML丰富文本,就按照丰富文本格式显示,否则按照普通无格式文本显示。除了自动判断文本格式,还可以用<br>
<div class="code">void setTextFormat(Qt::TextFormat)</div>
明确指定当前文本格式,可选的有三种格式,默认是 Qt::AutoText,自动判断;如果设置为
Qt::PlainText,就是强制作为普通无格式文本显示;如果设置为 Qt::RichText,那就一定作为丰富文本格式显示。<br>
<br>
对于丰富文本里带有的超链接文本,默认情况下 QLabel
是不会根据用户点击打开超链接的,如果希望用户点击超链接之后,自动用系统浏览器打开超链接,那么可以设置 openExternalLinks 属性为
true:<br>
<div class="code">void setOpenExternalLinks(bool open) </div>
<br>
对于长文本显示,将标签控件设置得足够大,就可以显示多行文本,标签控件默认不会自动换行,要让标签控件的文本换行,有两种方式:一是改变标签的文本内容,手动加
"\r\n" 或者 "<br>" 换行字符;另一种是设置 setWordWrap(true),wordWrap 属性为 true
时,自动根据文本长度换行显示。<br>
<br>
(2)像素图设置<br>
然后是像素图 QPixmap 的显示,QPixmap
类是专门用于将图片文件或者用代码绘制的图形显示到屏幕上,凡是各种控件界面显示用到的图标、图片等,一般都先用 QPixmap
加载,然后设置给控件来显示。QPixmap 加载一个图片文件是非常简单的:<br>
<div class="code">bool QPixmap::load(const QString & fileName, const
char * format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor)</div>
参数里第一个 fileName 是文件名,可以用绝对路径,也可以用相对路径。QtCreator
运行生成的程序时,相对路径是目标程序的工作路径,也就是影子构建路径,而不是源代码路径或 exe 文件路径,不清楚的读者请看 2.4 节末尾部分。<br>
参数第二个 format 是图片的格式字符串,可以不设置格式字符串,该函数会自动根据文件扩展名判断图片文件格式。Qt 支持的图片格式很多,主流的
BMP、JPG、PNG、XPM 等都支持,具体请查阅帮助文档索引 Reading and Writing Image Files。<br>
参数里第三个 flags 是像素图的颜色标志,默认的标志位是 Qt::AutoColor,如果图片的一个像素只占 1
bit,说明是黑白图,那么加载后是单色的黑白像素图,如果是彩色图,那就按照桌面设置的默认颜色深度来加载图片。<br>
flags 其他两个可选的标志位:对于 Qt::ColorOnly,就是全部当作彩色图,按照桌面设置的颜色深度(一般是真彩色)加载所有图片;对于
Qt::MonoOnly,就是全部转成单色的黑白图片加载。<br>
load() 函数如果加载成功就返回 true,否则返回 false。加载图片成功之后就可以将 QPixmap 对象设置给标签显示。<br>
<br>
(3)短片设置<br>
接下来是关于短片的显示,QMovie 类不是真的可以放电影,它其实仅支持无声的动态图格式,比如常见的 GIF 图,还有一种基于 PNG 的开源 MNG
动态图。因为是动态图,所以不是一次性加载的,没有 load
函数,而是通过设置文件名并播放的形式打开动态图。采取影片播放形式,首先是设置文件名,可以通过构造函数或者设置文件名函数指定:<br>
<div class="code">QMovie(const QString & fileName, const QByteArray
& format = QByteArray(), QObject * parent = 0)</div>
<div class="code">void QMovie::setFileName(const QString & fileName)</div>
构造函数里的 format 也是动态图格式,可以不指定格式字符串,QMovie 会根据文件扩展名自动判断格式。<br>
如果要判断指定的文件是否被支持,那么可以用后面的 error() 信号判断或者用下面函数判断动态图是否可用:<br>
<div class="code">bool QMovie::isValid() const</div>
<br>
设置文件名之后,就可以利用标签控件的 setMovie() 函数把 QMovie 对象设置给标签,然后开始播放:<br>
<div class="code">void QMovie::start() //槽函数,开始播放</div>
当然播放过程中,可以进行暂停或停止:
<div class="code">void QMovie::setPaused(bool paused) //槽函数,bool参数控制暂停或继续</div>
<div class="code">void QMovie::stop() //槽函数,停止播放,下次 start() 会从头播放</div>
<br>
播放过程中除了暂停、继续、停止等,还可以进行跳帧:<br>
<div class="code">bool QMovie::jumpToNextFrame() //跳到下一帧</div>
<div class="code">bool QMovie::jumpToFrame(int frameNumber) //跳到指定序号的帧</div>
跳帧的时候,有可能没有下一帧或者没有指定帧,跳转失败就会返回 false。<br>
动态图帧的总数可以用如下函数获取:<br>
<div class="code">int QMovie::frameCount() const</div>
一般情况下,这个函数会返回正确的计数,但是注意,如果有些动态图格式不支持总帧数计数,那么这个函数会返回 0。<br>
<br>
获取当前帧号和帧的像素图,使用下面函数:<br>
<div class="code">int QMovie::currentFrameNumber() const</div>
<div class="code">QPixmap QMovie::currentPixmap() const</div>
播放过程中有几个重要的信号,如下所示:<br>
<div class="code">void QMovie::error(QImageReader::ImageReaderError error)
//打开动态图出错时发的信号</div>
<div class="code">void QMovie::finished() //播放结束信号</div>
<div class="code">void QMovie::frameChanged(int frameNumber) //当前帧号变化信号</div>
<div class="code">void QMovie::started() //开始播放的信号</div>
无论是用 start() 播放短片还是 jumpTo*** 函数跳帧,一定要在这些加载图片帧的函数之前,关联打开出错的 error()
信号,这样才能知道加载图片帧的时候是否出错以及错误原因。QImageReader::ImageReaderError
枚举类型请查看帮助文档,这里不列举了。<br>
<br>
动态图比较有意思的是自带循环计数,可以用如下函数获取循环次数:<br>
<div class="code">int QMovie::loopCount() const</div>
如果返回值为 0,代表仅播放一次,不循环;而对于有些 GIF 图片,会返回 -1,代表无限循环播放。QMovie
还有其他设置播放速度、背景色、拉伸图片大小等函数,这里不列举了。<br>
<br>
(4)内容对齐、边框、伙伴设置<br>
上面讲了不少关于 QMovie 的内容,是因为后面例子用到了。现在回到 QLabel 类的介绍,无论是用标签显示文本还是图片,都可以设置内容的对齐方式:<br>
<div class="code">void QLabel::setAlignment(Qt::Alignment) </div>
默认的对齐方式是左对齐和垂直居中,当然也可以设置为其他的对齐方式,水平方向有:<br>
Qt::AlignLeft(左对齐)、Qt::AlignRight(右对齐)、Qt::AlignHCenter(水平居中)、
Qt::AlignJustify(两端对齐)。<br>
垂直方向的对齐有:<br>
Qt::AlignTop(从顶部起)、Qt::AlignBottom(从底部起)、Qt::AlignVCenter(垂直居中)、
Qt::AlignBaseline(基线对齐)。<br>
还有一个常量 Qt::AlignCenter,就是水平和垂直都居中,等同于 AlignVCenter | AlignHCenter。<br>
水平方向和垂直方向的标志为可以用 | 位或运算符同时启用。<br>
<br>
标签控件除了设置内部文本或图片的显示方式,因为基类是 QFrame,所以能设置丰富的边框格式,默认的标签是扁平的,没有边框,如果调用如下函数:<br>
<div class="code">void QFrame::setFrameStyle(int style)</div>
就可以改变边框风格,比如 QFrame::Panel | QFrame::Sunken 就是三维凹槽风格的边框。具体的 style 参考基类
QFrame 的帮助文档。<br>
<br>
QLabel 最后一部分内容是关于伙伴快捷键的,在 QLabel 文本里面加上如 "&P"
字样,然后把标签控件的伙伴设置为其他控件,就可以为伙伴设置快捷键 Alt+P 。例如:<br>
<div class="code"> QLineEdit *phoneEdit = new QLineEdit(this); <br>
QLabel *phoneLabel = new QLabel("&Phone:", this); <br>
phoneLabel->setBuddy(phoneEdit); </div>
<br>
<div class="os2">5.5.3 图片浏览示例</div>
<br>
这个示例就是用 QLabel 控件做一个浏览图片的程序,因为图片有可能比较大,需要用到 QScrollArea
包裹标签控件,这样就能利用滚动区域显示大图。对于动态图,需要播放、停止等按钮,并通过一个水平滑动条展示动态图播放进度。大概的功能就是这些,下面开始这个例子的编
写。<br>
打开 QtCreator,新建一个 Qt Widgets Application 项目,在新建项目的向导里填写:<br>
①项目名称 imgshow,创建路径 D:\QtProjects\ch05,点击下一步;<br>
②套件选择里面选择全部套件,点击下一步;<br>
③基类选择 QWidget,点击下一步;<br>
④项目管理不修改,点击完成。<br>
建好项目之后,打开窗体 widget.ui 文件,进入设计模式,按照下图拖入控件:<br>
<center><img src="images/ch05/ch05-05-02.png" alt="ui" width="800"></center>
首先把主界面窗体大小设置为 480*400,这样能容纳较大的标签控件。<br>
界面里第一行是一个标签控件,objectName 为 labelShow,文本内容清空,因为是用来显示图片用的。<br>
标签控件占用矩形 geometry 为 X:10,Y:10,宽度:461,高度:321,占据着窗体最大的一块地皮。<br>
之前提到要用滚动区域显示大图,现在 labelShow 的矩形是为后面代码里的滚动区域对象占据的,利用滚动区域显示大图。<br>
<br>
主界面第二行的控件是四个普通按钮,第一个按钮文本是 "打开图片",objectName 为 pushButtonOpenPic;<br>
第二个按钮文本是 "打开动态图",objectName 为 pushButtonOpenMov;<br>
第三个按钮文本是 "播放",objectName 为 pushButtonStart;<br>
第四个按钮文本是 "停止",objectName 为 pushButtonStop。<br>
调整四个按钮,让它们处于对齐状态,均匀分布在水平线上。<br>
主界面第三行控件是一个水平滑动条,objectName 为
horizontalSlider。这个水平滑动条适用于显示动态图播放进度的,因此与右边三个按钮对齐。<br>
<br>
主界面就是如图上设置,现在为四个按钮都添加 clicked() 信号对应的槽函数:<br>
<center><img src="images/ch05/ch05-05-03.png" alt="slot"></center>
添加四个按钮的槽函数之后,保存界面文件,回到代码编辑模式,添加例子需要的代码。<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;"><QPixmap></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;"><QMovie></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;"><QImageReader></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;">public</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:#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;">RecvPlayError</span><span
style=" color:#000000;">(</span><span style=" color:#800080;">QImageReader</span><span
style=" color:#000000;">::</span><span style=" color:#800080;">ImageReaderError</span><span
style=" color:#c0c0c0;"> </span>error<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;">RecvFrameNumber</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">int</span><span style=" color:#c0c0c0;"> </span>frameNumber<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_pushButtonOpenPic_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_pushButtonOpenMov_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_pushButtonStart_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_pushButtonStop_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="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//像素图指针</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QPixmap</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">m_pPixMap</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;">QMovie</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#800000;">m_pMovie</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;">bool</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_bIsMovie</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;">bool</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_bIsPlaying</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;">ClearOldShow</span><span
style=" color:#000000;">();</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">};</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#endif</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">//</span><span style=" color:#c0c0c0;"> </span><span style=" color:#008000;">WIDGET_H</span></pre>
</div>
在 widget.h 头文件新加了三个头文件包含,<QPixmap> 是像素图的头文件,<QMovie>
是动态图(短片)的头文件,<QImageReader> 是图片读取类的头文件,QMovie 类就是使用 QImageReader
读取动态图里一帧帧图像的,如果读取出错,就发出读取错误信号,信号里的参数是 QImageReader::ImageReaderError
类型,因此提前包含 <QImageReader> 。<br>
<br>
在 Widget 类声明里,我们手动添加两个公有槽函数,RecvPlayError()
是用于接收动态图播放错误的信号,RecvFrameNumber() 用于在动态图播放时更新水平滑动条。这两个信号的参数不是凭空想象的,而是根据 Qt
帮助文档里面 QMovie 类信号来确定的,要注意查阅 Qt 帮助文档。<br>
<br>
Widget 类声明里四个按钮的槽函数是刚才从设计模式添加的,这里不需要变动私有槽函数。然后我们在类声明里面添加私有成员变量:<br>
m_pPixMap 是用于保存像素图 QPixmap 对象的指针;<br>
m_pMovie 是用于保存动态图 QMovie 对象的指针;<br>
m_bIsMovie 用于标识是否处于动态图(短片)浏览模式;<br>
m_bIsPlaying 表示是否处于动态图的播放过程中。<br>
最后一个私有成员函数 ClearOldShow() 用于在打开新图之前,清理旧的像素图、动态图对象,并重置两个标志位变量。<br>
<br>
头文件内容就上面那些,下面为源文件 widget.cpp 添加实体功能代码,首先是头文件包含和构造函数部分:<br>
<div class="code"><span style=" color:#000080;">#include</span><span style=" color:#c0c0c0;">
</span><span style=" color:#008000;">"widget.h"</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">"ui_widget.h"</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><QDebug></span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000080;">#include</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;"><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;"><QScrollArea></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="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">Widget</span><span style=" color:#000000;">(</span><span
style=" color:#800080;">QWidget</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#000000;">*</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">)</span><span style=" color:#c0c0c0;"> </span><span style=" color:#000000;">:</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QWidget</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">parent</span><span
style=" color:#000000;">),</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">new</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">Ui</span><span style=" color:#000000;">::</span><span style=" color:#800080;">Widget</span><span
style=" color:#000000;">)</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setupUi</span><span
style=" color:#000000;">(</span><span style=" color:#808000;">this</span><span style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//初始化成员变量</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</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:#800000;">m_pMovie</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:#800000;">m_bIsMovie</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">false</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_bIsPlaying</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">false</span><span style=" color:#000000;">;</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//获取标签矩形</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QRect</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">rcLabel</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;">labelShow</span><span style=" color:#000000;">-></span><span
style=" color:#000000;">geometry</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;">QScrollArea</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">*</span><span style=" color:#000000;">pSA</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;">QScrollArea</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:#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;">pSA</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setWidget</span><span
style=" color:#000000;">(</span><span style=" color:#800000;">ui</span><span style=" color:#000000;">-></span><span
style=" color:#800000;">labelShow</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;">pSA</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setGeometry</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">rcLabel</span><span
style=" color:#000000;">);</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//打印支持的图片格式</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#800080;">QImageReader</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">supportedImageFormats</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:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#800080;">QMovie</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">supportedFormats</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>
widget.cpp 新包含的头文件有四个,调试类的头文件就不多说了,<QFileDialog>
是打开文件对话框的头文件,<QScrollArea> 是滚动区域的头文件,<QMessageBox> 是消息框的头文件。<br>
<br>
在构造函数里,首先对四个成员变量 m_pPixMap、m_pMovie、m_bIsMovie、m_bIsPlaying 进行初始化。<br>
<br>
然后是关于滚动区域的代码段,获取了标签控件 labelShow 占用的矩形 rcLabel ,<br>
新建了一个 QScrollArea 滚动区域对象,对象指针为 pSA ,pSA 父对象是主窗口,<br>
主窗口销毁时,子对象都会自动销毁,所以后面不需要手动 delete 这个 pSA 指向的对象。<br>
让滚动区域包裹标签,只需要一句 pSA->setWidget(ui->labelShow) 搞定,<br>
滚动区域包裹标签之后,将滚动区域对象的矩形设置为原先标签占的矩形,这样主界面就能看到滚动区域对象了,<br>
标签控件会自动显示在滚动区域内部。<br>
构造函数里最后两句是打印支持的静态图格式和动态图格式。<br>
<br>
构造函数讲完了,下面是析构函数:<br>
<div class="code"><span style=" color:#800080;">Widget</span><span style=" color:#000000;">::~</span><span
style=" font-style:italic; color:#000000;">Widget</span><span style=" color:#000000;">()</span>
<pre 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;">ClearOldShow</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:#800000;">ui</span><span style=" color:#000000;">;</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">}</span></pre>
</div>
析构函数内部调用了私有函数 ClearOldShow(),用于清理像素图对象和动态图对象。通常 Qt
的控件对象不需要自己清理,因为它们有父对象,父对象销毁时,子对象自动销毁。但是这里用到的像素图、动态图是我们自己的 new
的,它们其实没有父对象,所以手动清理了。<br>
<br>
私有的清理函数 ClearOldShow() 代码如下:<br>
<div class="code"><span style=" color:#808000;">void</span><span style=" color:#c0c0c0;">
</span><span style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">ClearOldShow</span><span style=" color:#000000;">()</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#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;">labelShow</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;">if</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</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:#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:#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_pPixMap</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</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:#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_pMovie</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:#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:#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:#800000;">m_bIsPlaying</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:#800000;">m_pMovie</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">stop</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;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pMovie</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pMovie</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:#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_bIsMovie</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">false</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_bIsPlaying</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">false</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>
这个清理函数首先调用标签对象的 clear() 函数,清空标签显示的所有内容。<br>
如果像素图指针 m_pPixMap 不为空,那就删除像素图,并将指针置空。<br>
如果动态图指针 m_pMovie 不为空,先判断是否处于播放中,如果在播放中就先停止播放,然后把动态图对象删除,指针也置空。<br>
最后将两个标志位成员变量都重置为 false。<br>
ClearOldShow() 会在析构函数和新打开图片时调用,用于清理旧的像素图和动态图,并重置标志位。<br>
<br>
接下来是 "打开图片" 按钮的槽函数:<br>
<div class="code"><span style=" color:#808000;">void</span><span style=" color:#c0c0c0;">
</span><span style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">on_pushButtonOpenPic_clicked</span><span style=" color:#000000;">()</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strFileName</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;">strFileName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getOpenFileName</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:#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:#008000;">"Pictures</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">(*.bmp</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.jpg</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.jpeg</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.png</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.xpm);;All</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*)"</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:#000000;">strFileName</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">())</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<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;">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:#000000;">ClearOldShow</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:#000080;">qDebug</span><span
style=" color:#000000;">()<<</span><span style=" color:#000000;">strFileName</span><span
style=" color:#000000;">;</span></pre>
<pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">//新建像素图</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</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;">QPixmap</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_pPixMap</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">load</span><span
style=" color:#000000;">(</span><span style=" color:#000000;">strFileName</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:#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:#800000;">ui</span><span
style=" color:#000000;">-></span><span style=" color:#800000;">labelShow</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setPixmap</span><span
style=" color:#000000;">(*</span><span style=" color:#800000;">m_pPixMap</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;">labelShow</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">setGeometry</span><span
style=" color:#000000;">(</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</span><span
style=" color:#000000;">-></span><span style=" color:#000000;">rect</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><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">bool</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#008000;">状态</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_bIsMovie</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">false</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:#800000;">m_bIsPlaying</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#808000;">false</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:#808000;">else</span></pre>
<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;">delete</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</span><span
style=" color:#000000;">;</span><span style=" color:#c0c0c0;"> </span><span style=" color:#800000;">m_pPixMap</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:#008000;">//提示失败</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QMessageBox</span><span
style=" color:#000000;">::</span><span style=" color:#000000;">critical</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></pre>
<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;">tr</span><span
style=" color:#000000;">(</span><span style=" color:#008000;">"打开图片失败,文件名为:\r\n%1"</span><span
style=" color:#000000;">).</span><span style=" color:#000000;">arg</span><span style=" color:#000000;">(</span><span
style=" color:#000000;">strFileName</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>
先解释一下 QFileDialog::getOpenFileName() 静态函数,这个函数与之前 5.3.4 节
QFileDialog::getOpenFileUrl() 函数类似,本节的 QFileDialog::getOpenFileName()
用于获取真正的文件系统路径,而之前的 QFileDialog::getOpenFileUrl() 是获取文件 URL。
QFileDialog::getOpenFileName() 函数声明如下:<br>
<div class="code">QString QFileDialog::getOpenFileName(QWidget * parent =
0, const QString & caption = QString(), const QString & dir =
QString(), const QString & filter = QString(), QString *
selectedFilter = 0, Options options = 0)</div>
parent 是父窗口指针;<br>
caption 是打开文件对话框标题;<br>
dir 是初始显示的文件夹路径,QtCreator 运行程序时默认为工作路径(影子构建路径);<br>
filter 是文件扩展名筛选格式串,与 5.3.4 介绍的是一样的;<br>
selectedFilter 是从多个筛选格式串默认选中一个;<br>
options 是打开文件对话框的选项,一般用不着。<br>
如果用户选择了正确的文件名,就返回有用的文件名字符串,否则返回空串。<br>
<br>
在上面的 on_pushButtonOpenPic_clicked() 槽函数里,打开文件对话框的父窗口是主界面 this,标题是 "打开静态图片"
,初始显示的文件路径 "",为空的,就是默认的工作路径开始,QtCreator 运行程序时的工作路径默认就是影子构建路径,筛选格式串为
"Pictures (*.bmp *.jpg *.jpeg *.png *.xpm);;All files(*)"
,这个筛选格式串其实有两个,双分号前面的是正常的图片筛选字符串,双分号后面的是不筛选,所有文件都能看到。<br>
<br>
在获取图片文件名 strFileName ,先判断字符串是否为空,如果为空就返回,在文件名不为空的情况下,继续后面代码。<br>
得到确实存在的文件名之后,调用 ClearOldShow() 清空旧的内容,并打印新的文件名。<br>
<br>
清空旧的内容之后,我们新建一个 QPixmap 对象,指针存到 m_pPixMap,<br>
然后调用 m_pPixMap->load(strFileName) 尝试加载图片文件:<br>
如果加载成功,那就把像素图设置给标签对象,并将标签对象的矩形设置为与像素图的矩形一样大,并设置两个标志位成员变量都为 false,因为这里是处理静态图显
示的。<br>
如果加载失败,那么删除像素图,将该指针置空,然后弹出消息框提示打开出错。<br>
<br>
QMessageBox::critical() 与其他两个
QMessageBox::information()、QMessageBox::warning() 是完全类似的,只不过
QMessageBox::critical() 用于提示严重错误,图标一般是个红底 X 号。<br>
<br>
静态图片打开并显示的过程是比较简单的,因为不涉及到播放,下面来看看动态图的打开过程。<br>
"打开动态图" 按钮的槽函数内容相对较多,我们拆成三块来讲解,首先是函数头和文件名获取、判断:<br>
<div class="code"><span style=" color:#808000;">void</span><span style=" color:#c0c0c0;">
</span><span style=" color:#800080;">Widget</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">on_pushButtonOpenMov_clicked</span><span style=" color:#000000;">()</span>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#000000;">{</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QString</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">strFileName</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;">strFileName</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">=</span><span style=" color:#c0c0c0;"> </span><span
style=" color:#800080;">QFileDialog</span><span style=" color:#000000;">::</span><span
style=" color:#000000;">getOpenFileName</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:#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:#008000;">"Movies</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">(*.gif</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">*.mng);;All</span><span
style=" color:#c0c0c0;"> </span><span style=" color:#008000;">files(*)"</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:#000000;">strFileName</span><span
style=" color:#000000;">.</span><span style=" color:#000000;">isEmpty</span><span
style=" color:#000000;">())</span></pre>
<pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span
style=" color:#c0c0c0;"> </span><span style=" color:#000000;">{</span></pre>
<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;">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