基于Qt的多媒体综合应用程序设计(2)

框架结构图等

1.多媒体综合应用程序设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现文字处理程序跳转、绘图程序跳转、图像处理程序跳转、音频播放器跳转、视频播放器跳转和动画播放器跳转功能
其框架结构图如图1-8所示:
基于Qt的多媒体综合应用程序设计(2)
图1-8 多媒体综合应用程序框架结构图

2.文字处理程序的设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现文本的打开和新建功能;实现对文本样式进行编辑,包括设置字体、设置字号、设置颜色、文字加粗、倾斜文字、增加下划线、修改排列方式等功能;实现复制、剪切、粘贴、撤销、恢复等文本处理功能;在工具栏中为各项功能添加相应的图标;为文字处理程序设置标题和相关信息。
其框架结构图如图1-9所示:
基于Qt的多媒体综合应用程序设计(2)
图1-9 文字处理程序框架结构图

3.绘图程序的设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现文本的打开和新建功能;区分各种形状以及绘图颜色、绘图线宽、绘图风格、画笔顶帽、画笔连接点、填充模式、铺展效果、画刷颜色和画刷风格设置等。
其框架结构图如图1-10所示:
基于Qt的多媒体综合应用程序设计(2)
图1-10 绘图程序框架结构图

4.图像处理程序的设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现打开电脑中选择的相应图像,并将选中的图像文件在主窗口中的图像显示区域进行显示;新建一个区域进行图像编辑操作;对图像进行相应编辑,包括旋转、镜像、放大、缩小等功能;可对图像进行打印操作。
其框架结构图如图1-11所示:
基于Qt的多媒体综合应用程序设计(2)
图1-11 图像处理程序框架结构图

5.音频播放器的设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现在音频播放器中打开电脑中音频文件,支持多种文件格式,如mp3等;在播放列表中添加、移除、清空相应的音频文件;实现音频文件的播放、暂停、停止、上一曲、下一曲、音量调节、进度调节等功能。
其框架结构图如图1-12所示:
基于Qt的多媒体综合应用程序设计(2)
图1-12 音频播放器框架结构图

6.视频播放器的设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现视频的播放、暂停、停止、全屏、退出全屏、快进、快退、上一个、下一个的功能操作;对正在播放的视频进行编辑,包括亮度调整、对比度调整等操作;对正在播放的视频进行音量调节和进度调节。
使用传递到qvideowidget中的qmediaplayer对象来控制视频输出。为了提供应用程序播放列表功能,我们还使用qplaylist对象。要**对话框上的播放和停止等各种功能,单击按钮的事件会发出play()和stop()信号,这些信号连接到qmediaplayer的play()和stop()插槽。
其框架结构图如图1-13所示:
基于Qt的多媒体综合应用程序设计(2)
图1-13 视频播放器框架结构图

7.动画播放器的设计思路
首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,利用定时器实现时钟动画,表盘内包括时针、分针、秒针,显示时间与PC端的时间保持一致。
其框架结构图如图1-14所示:
基于Qt的多媒体综合应用程序设计(2)
图1-14 时钟动画框架结构图

主窗体的基本元素
1.菜单栏
菜单是一系列命令的列表。为了实现菜单、工具栏按钮、键盘快捷方式等命令的一致性,Qt使用动作(Action)来表示这些命令。Qt的菜单就是由一系列的QAction动作对象构成的列表,而菜单栏则是包容菜单的面板,它位于主窗口顶部、主窗口标题栏的下面。一个主窗口最多只有一个菜单栏。

2.状态栏
状态栏通常显示GUI应用程序的一些状态信息,它位于主窗口的底部。用户可以在状态栏上添加、使用Qt窗口部件。一个主窗口最多只有一个状态栏。

3.工具栏
工具栏是由一系列的类似于按钮的动作排列而成的面板,它通常由一些经常使用的命令(动作)组成。工具栏位于菜单栏的下面、状态栏的上面,可以停靠在主窗口的上、下、左、右四个方向上。一个主窗口可以包含多个工具栏。

4.锚接部件
锚接部件作为一个容器使用,以包容其他窗口部件来实现某些功能。例如,Qt设计器的属性编辑器、对象监视器等都是由锚接部件包容其他的Qt窗口部件来实现的。它位于工具栏区的内部,可以作为一个窗口*地浮动在主窗口上面,也可以像工具栏一样停靠在主窗口的上、下、左、右四个方向上。一个主窗口可以包含多个锚接部件。

5.中心部件
中心部件处在锚接部件区的内部、主窗口的中心。一个主窗口只有一个中心部件。

主窗体元素的实现
1.动作(Action)的实现
(a) openFileAction =new QAction(QIcon(“open.png”),tr(“打开”),this):在创建“打开文件”动作的同时,指定了此动作使用的图标、名称及父窗口。
(b) openFileAction->setShortcut(tr(“Ctrl+O”)):设置此动作的组合键为【Ctrl+O】。
(c ) openFileAction->setStatusTip(tr(“打开一个文件”)):设定了状态栏显示,当鼠标光标移至此动作对应的菜单条目或工具栏按钮上时,在状态栏上显示“打开一个文件”的提示。
实现打印文本和图像、图像缩放、旋转和镜像的动作(Action)的代码位于ImgProcessor::createActions()方法中。

2.菜单(Menus)的实现
在实现了各个动作之后,需要将它们通过菜单、工具栏或快捷键的方式体现出来,以下是菜单的实现函数createMenus()代码。

3.工具栏(ToolBars)的实现
实现相对应的工具栏createToolBars()时,主窗口的工具栏上可以有多个工具条,通常采用一个菜单对应一个工具条的方式,也可根据需要进行工具条的划分。
工具条是一个可移动的窗口,它可停靠的区域由QToolBar的allowAreas决定,包括Qt::LeftToolBarArea、Qt::RightToolBarArea、Qt::TopToolBarArea、Qt::BottomToolBarArea和Qt::AllToolBarAreas。默认为Qt::AllToolBarAreas,启动后默认出现于主窗口的顶部。可通过调用setAllowAreas()函数来指定工具条可停靠的区域,例如:
fileTool->setAllowedAreas(Qt::TopToolBarArea|Qt::LeftToolBarArea);
此函数限定文件工具条只可出现在主窗口的顶部或左侧。工具条也可通过调用setMovable()函数设定可移动性,例如:
fileTool->setMovable(false);
指定文件工具条不可移动,只出现于主窗口的顶部。

4.文本编辑各类之间的划分与关系
文本编辑各类之间的划分与关系如图2-1所示:
基于Qt的多媒体综合应用程序设计(2)
图2-1 文本编辑各类之间的划分与关系

绘图区域的实现
1.绘图相关函数:
setShape()函数可以设置形状;
setPen()函数可以设置画笔;
setBrush()函数可以设置画刷;
setFillRule()函数可以设置填充模式。

2.利用QPainterPath绘制简单图形
利用QPainterPath绘制简单图形,QPainterPath类为QPainter类提供了一个存储容器,里面包含了所要绘制的内容的集合及绘制的顺序,如长方形、多边形、曲线等各种任意图形。当需要绘制此预先存储在QPainterPath对象中的内容时,只需调用QPainter类的drawPath()函数即可。
QPainterPath对象的当前点自动处在上一部分图形内容的结束点上,若下一部分图形的起点不在此结束点,则需调用moveTo()函数将当前点移动到下一部分图形的起点。

3.事件mousePressEvent()
重定义鼠标按下事件mousePressEvent(),在按下鼠标时,记录当前的鼠标位置值startPos。QWidget的mouseTracking属性指示窗体是否追踪鼠标,默认为false(不追踪),即在至少有一个鼠标按键按下的前提下移动鼠标才触发mouseMoveEvent()事件,可以通过setMouseTracking(bool enable)方法对该属性值进行设置。如果设置为追踪,则无论是否有鼠标按键按下,只要鼠标移动,就会触发mouseMoveEvent()事件。

4.重画函数paintEvent()
重画函数paintEvent()完成绘制区窗体的更新工作,只需调用drawPixmap()函数将用于接收图形绘制的QPixmap对象绘制在绘制区窗体控件上即可。

5.调整绘制区大小函数resizeEvent()
当窗体的大小发生改变时,效果看起来虽然像是绘制区大小改变了,但实际能够进行绘制的区域仍然没有改变。因为绘图的大小并没有改变,还是原来绘制区窗口的大小,所以在窗体尺寸变化时应及时调整用于绘制的QPixmap对象的大小。

6.QImage与Qpixmap的区别
(1)QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的。
(2)QPixmap依赖于所在的平台的绘图引擎,故例如反锯齿等一些效果在不同的平台上可能会有不同的显示效果,QImage使用Qt自身的绘图引擎,可在不同平台上具有相同的显示效果。
(3)目前的Qt会把QPixmap都存储在graphics memory中,QImage是存储在客户端的,是独立于硬件的。在 X11, Mac 以及 Symbian平台上,QPixmap 是存储在服务器端,而QImage则是存储在客户端,在Windows平台上,QPixmap和QImage都是存储在客户端,并不使用任何的GDI资源。
(4)由于QImage是独立于硬件的,也是一种QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在GUI线程中处理,使用这一方式可以很大幅度提高UI响应速度。

GraphicsView的坐标系统
1.场景坐标
场景坐标是所有图元的基础坐标系统。场景坐标系统描述了顶层的图元,每个图元都有场景坐标和相应的包容框。场景坐标的原点在场景中心,坐标原点是x轴正方向向右,y轴正方向向下。QGraphicsScene类的坐标系以中心为原点(0,0)。

2.视图坐标
视图坐标是窗口部件的坐标。视图坐标的单位是像素。QGraphicsView视图的左上角是(0,0),x轴正方向向右,y轴正方向向下。所有的鼠标事件最开始都是使用视图坐标。QGraphicsView类继承自QWidget类,因此它与其他的QWidget类一样,以窗口的左上角作为自己坐标系的原点。

3.图元坐标
图元使用自己的本地坐标,这个坐标系统通常以图元中心为原点,这也是所有变换的原点。图元坐标方向是x轴正方向向右,y轴正方向向下。创建图元后,只需注意图元坐标就可以了,QGraphicsScene和QGraphicsView会完成所有的变换。
QGraphicsItem类的坐标系,若在调用QGraphicsItem类的paint()函数重绘图元时,则以此坐标系为基准。

1.使用QMediaPlay播放音乐文件
QMediaPlayer可以播放经过压缩的音频或视频文件,如:MP3、MP4、wmv,avi等,QMediaPlayer可以播放单个文件,也可以和QMediaPlaylist类结合,对一个播放列表进行播放。所以使用QMediaPalyer和QMediaPlayerlist可以轻松设计一个自己的音乐或视频播放器。

2.插入视频
Qt中插入视频的方法很多,有QVideoPlayer方法,也有用Phonon的,也可以在一个QMainwindow界面中,划出一个区域,播放视频,并可以控制视频的切换、停止、暂停、循环。
MainWindow自带layout,所以需要自定义layout并把它设置成中心layout,否则将会出现不能设置layout错误。

3.进度条设置
Qt提供了两种显示进度条的方式:
一种是QProgressBar,提供了一种横向或者纵向显示进度的控件表示方式,用来描述任务的完成情况;另一种是QProgressDialog,提供了一种针对慢速过程的进度对话框表示方式,用于描述任务完成的进度情况。标准的进度条对话框包括一个进度显示条、一个取消按钮及一个标签。
(1)详细描述
可以通过setRange()来设置进度的最小值和最大值(取值范围),也可使用setMinimum()和setMaximum()来单独设定;成员函数setValue()用于设置当前的运行值;调用reset()则会让进度条重新回到开始。
当前值设置完成以后,将显示已完成的百分比,计算百分比的公式为:(value() - minimum()) / (maximum() - minimum())。
如果最小值和最大值都设置为0,进度条会显示一个繁忙指示,而不会显示当前值。有时候这很有用,例如:当使用QNetworkAccessManager下载东西,无法确定被下载项大小时,可以通过setOrientation()指定进度条的方向 - 水平/垂直。此外,成员函数setInvertedAppearance()用于设置进度条的行进方向,如果参数为true,可将进度方向设置为默认方向的反方向。
如果不需要显示进度条上的文本,可以使用setTextVisible()来隐藏。
(2)读取方向
枚举QProgressBar::Direction :指定垂直进度条文本的读取方向
基于Qt的多媒体综合应用程序设计(2)
这个属性对水平进度条没有影响。默认情况下,读取方向为:QProgressBar::TopToBottom
(3)进度方向
当水平进度时,可以从左到右,也可以从右到左;同样,垂直显示进度时,可以从上到下,也可以从下到上。

动画架构
动画框架由基类QAbstractAnimation和它的两个儿子QVariantAnimation和QAnimationGroup组成。QAbstractAnimation是所有动画类的祖宗。它包含了所有动画的基本属性。比如开始,停止和暂停一个动画的能力。它也可以接收时间改变通知。
动画框架又进一步提供了QProertyAnimation类。它继承自QVariantAnimation并对某个Qt属性执行动画。此类对属性执行一个宽松曲线插值。所以当你想去动画一个值时,你可以把它声明为一个属性,并且让你的类成为一个QObject。这给予我们极大的*度来动画那些已存在的widget和其它QObject。
复杂的动画可以通过建立一个QAbstractAnimation的树来构建。这个树通过使用QAnimationGroups来创建,QAnimationGroups作为其它动画的容器。注意动画组也是从QAbstractAnimation派生的,所以动画组可以再包含其它动画组。
动画框架可以单独使用,同时也被设计为状态机框架的一部分。状态机提供了一个特定的状态可以用来播放动画。在进入或退出某个状态时QState也可以设置属性们,并且这个特定的动画状态将在指定QPropertyAnimation时给予的值之间做插值运算。后面我们要进一步介绍此问题。
在场景的背后,动画被一个全局定时器收集,这个定时器发送update到所有的正在播放的动画中。