第6章Qt5图形与图画课件.ppt
第6章 Qt 5图形与图画,6.1 Qt 5位置相关函数,6.2 Qt 5基础图形的绘制,6.3 Qt 5双缓冲机制,6.4 Qt 5 SVG格式图片的显示,6.1 Qt 5位置相关函数,6.1.1 区别概述Qt提供了很多关于获取窗体位置及显示区域大小的函数,如x( )、y( )和pos( )、rect( )、size( )、geometry( )等,统称为“位置相关函数”或“位置函数”,如图6.1所示是几种主要的位置函数,图中清楚地标出了它们之间的区别。,6.1.2 使用举例,具体实现步骤如下。(1)新建Qt Gui应用(详见本书第1章1.3.1节),项目名称为“Geometry ”,基类选择“QDialog ”,类名命名为“Geometry”,取消“创建界面”复选框的选中状态。单击“下一步”按钮,最后单击“完成”按钮,完成该项目工程的建立。(2)Geometry类继承自QDialog类,在头文件中声明所需的控件(主要为QLabel类)及所需要的函数。打开“geometry.h”头文件,添加代码。,6.1.2 使用举例,(3)在构造函数中完成控件的创建以及初始化工作,打开“geometry.cpp”文件,添加代码。updateLabel()函数完成获得各位置函数的信息并显示功能,具体代码。重新定义QWidget的moveEvent()函数,响应对话框的移动事件,使得窗体在被移动时能够同步更新各函数的显示结果,具体代码如下:void Geometry:moveEvent(QMoveEvent *) updateLabel();重新定义QWidget的resizeEvent()函数,响应对话框的大小调整事件,使得在窗体大小发生改变时,也能够同步更新各函数的显示结果,具体代码如下:void Geometry:resizeEvent(QResizeEvent *) updateLabel();,6.1.2 使用举例,(4)运行程序,效果如图6.2所示。,6.2 Qt 5基础图形的绘制,6.2.1 绘图框架设计绘制各种基础图形使用的框架实例如图6.3所示。具体内容见代码CH602。,6.2.1 绘图框架设计,此实例的具体实现包含了两个部分的内容,一个是用于画图的区域PaintArea类,另一个是主窗口MainWidget类,如图6.4所示。,6.2.2 绘图区的实现,打开“paintarea.h”头文件,添加代码。PaintArea类的构造函数用于完成初始化工作,设置图形显示区域的背景色及最小显示尺寸,具体代码如下:#include paintarea.h#include PaintArea:PaintArea(QWidget *parent):QWidget(parent) setPalette(QPalette(Qt:white); setAutoFillBackground(true); setMinimumSize(400,400);,6.2.2 绘图区的实现,setShape()函数可以设置形状,setPen()函数可以设置画笔,setBrush()函数可以设置画刷,setFillRule()函数可以设置填充模式,具体代码实现如下:void PaintArea:setShape(Shape s) shape = s; update();void PaintArea:setPen(QPen p) pen = p; update();void PaintArea:setBrush(QBrush b) brush = b; update();void PaintArea:setFillRule(Qt:FillRule rule) fillRule =rule; update(); /重画绘制区窗体PaintArea类的重画函数代码。,6.2.2 绘图区的实现,其中, QPainter p(this):新建一个QPainter对象。 p.setPen(pen)、p.setBrush(brush):设置QPainter对象的画笔和画刷。 QRect rect(50,100,300,200):设定一个方形区域,为画长方形、圆角方形、椭圆等做准备。 static const QPoint points4=:创建一个QPoint的数组,包含四个点,为画多边形、多边线及点做准备。 int startAngle=30*16、int spanAngle =120*16:其中,参数startAngle表示起始角,为弧形的起始点与圆心之间连线与水平方向的夹角;参数spanAngle表示的是跨度角,为弧形起点、终点分别与圆心连线之间的夹角,如图6.5所示。,6.2.2 绘图区的实现, QPainterPath path:新建一个QPainterPath对象,为画路径做准备。 switch(shape):使用一个switch()语句,对所要画的形状做判断,调用QPainter的各个draw()函数完成图形的绘制。,6.2.2 绘图区的实现,(1)利用QPainter绘制图形(Shape)。Qt为开发者提供了丰富的绘制基本图形的draw函数,如图6.6所示。,6.2.2 绘图区的实现,(2)利用QPainterPath绘制简单图形。利用QPainterPath绘制简单图形,QPainterPath类为QPainter类提供了一个存储容器,里面包含了所要绘制的内容的集合及绘制的顺序,如长方形、多边形、曲线等各种任意图形。cubicTo()函数绘制的是贝赛尔曲线,如图6.7所示。,6.2.2 绘图区的实现,利用QPainterPath类可以实现QPainter类的draw()函数能够实现的所有图形。例如,对于QPainter:drawRect()函数,除了可用上面介绍的QPainterPath:addRect()的方式实现,还可以用如下方式实现:QPainterPath path;path.moveTo(0,0);path.lineTo(200,0);path.lineTo(200,100);path.lineTo(0,100);path.lineTo(0,0);,6.2.3 主窗口的实现,打开“mainwidget.h”头文件,添加代码。MainWiget类的构造函数中创建了各参数选择控件,打开“mainwiget.cpp”文件,添加代码。,6.2.3 主窗口的实现,其中, shapeComboBox-addItem(tr(Line),PaintArea:Line):QComboBox的addItem()函数可以仅插入文本,也可同时插入与文本相对应的具体数据,通常为枚举型数据,便于后面操作时确定选择的是哪个数据。 penStyleComboBox-addItem(tr(SolidLine),static_cast(Qt:SolidLine):选用不同的参数,对应画笔的不同风格,如图6.8所示。,6.2.3 主窗口的实现, penCapComboBox-addItem(tr(SquareCap),Qt:SquareCap):选用不同的参数,对应画笔顶帽的不同风格,如图6.9所示。,6.2.3 主窗口的实现, penJoinComboBox-addItem(tr(BevelJoin),Qt:BevelJoin):选用不同的参数,对应画笔连接点的不同风格,如图6.10所示。,6.2.3 主窗口的实现, fillRuleComboBox-addItem(tr(Odd Even),Qt:OddEvenFill):Qt为QPainterPath类提供了两种填充规则,分别是Qt:OddEvenFill和Qt:WindingFill,如图6.11所示。,6.2.3 主窗口的实现,其中,Qt:OddEvenFill填充规则判断的依据是从图形中某一点画一条水平线到图形外,若这条水平线与图形边线的交点数目为奇数,则说明此点位于图形的内部;若交点数目为偶数,则此点位于图形的外部,如图6.12所示。,6.2.3 主窗口的实现,而Qt:WindingFill填充规则的判断依据则是从图形中某一点画一条水平线到图形外,每个交点外边线的方向可能向上,也可能向下,将这些交点数累加,方向相反的相互抵消,若最后结果不为0则说明此点在图形内,若最后结果为0则说明在图形外,如图6.13所示。,6.2.3 主窗口的实现, spreadComboBox-addItem(tr(PadSpread),QGradient:PadSpread):铺展效果有三种,分别为QGradient:PadSpread、QGradient:RepeatSpread和QGradient:ReflectSpread。其中,PadSpread是默认的铺展效果,也是最常见的铺展效果,没有被渐变覆盖的区域填充单一的起始颜色或终止颜色;RepeatSpread效果与ReflectSpread效果只对线性渐变和圆形渐变起作用,如图6.14所示。,6.2.3 主窗口的实现, brushStyleComboBox-addItem(tr(SolidPattern),static_cast(Qt:SolidPattern):选用不同的参数,对应画刷的不同风格,如图6.15所示。,6.2.3 主窗口的实现,ShowShape()槽函数,根据当前下拉列表框中选择的选项,调用PaintArea类的setShape()函数设置PaintArea对象的形状参数,具体代码如下:void MainWidget:ShowShape(int value) PaintArea:Shape shape = PaintArea:Shape(shapeComboBox-itemData( value,Qt:UserRole).toInt(); paintArea-setShape(shape);,6.2.3 主窗口的实现,在此函数中获得与画笔相关的所有属性值,包括画笔颜色、画笔线宽、画笔风格、画笔顶帽及画笔连接点,共同构成QPen对象,并调用PaintArea对象的setPen()函数设置PaintArea对象的画笔属性。其他与画笔参数相关的响应函数完成的工作与此类似,具体代码如下:void MainWidget:ShowPenColor() QColor color = QColorDialog:getColor(static_cast(Qt:blue); penColorFrame-setPalette(QPalette(color); int value = penWidthSpinBox-value(); Qt:PenStyle style = Qt:PenStyle(penStyleComboBox-itemData( penStyleComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenCapStyle cap = Qt:PenCapStyle(penCapComboBox-itemData( penCapComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenJoinStyle join=Qt:PenJoinStyle(penJoinComboBox-itemData( penJoinComboBox-currentIndex(),Qt:UserRole).toInt(); paintArea-setPen(QPen(color,value,style,cap,join);,6.2.3 主窗口的实现,ShowPenWidth()槽函数的具体实现代码如下:void MainWidget:ShowPenWidth(int value) QColor color = penColorFrame-palette().color(QPalette:Window); Qt:PenStyle style = Qt:PenStyle(penStyleComboBox-itemData( penStyleComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenCapStyle cap = Qt:PenCapStyle(penCapComboBox-itemData( penCapComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenJoinStyle join=Qt:PenJoinStyle(penJoinComboBox-itemData( penJoinComboBox-currentIndex(),Qt:UserRole).toInt(); paintArea-setPen(QPen(color,value,style,cap,join);,6.2.3 主窗口的实现,ShowPenStyle()槽函数的具体实现代码如下:void MainWidget:ShowPenStyle(int styleValue) QColor color = penColorFrame-palette().color(QPalette:Window); int value = penWidthSpinBox-value(); Qt:PenStyle style = Qt:PenStyle(penStyleComboBox-itemData( styleValue,Qt:UserRole).toInt(); Qt:PenCapStyle cap = Qt:PenCapStyle(penCapComboBox-itemData( penCapComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenJoinStyle join=Qt:PenJoinStyle(penJoinComboBox-itemData( penJoinComboBox-currentIndex(),Qt:UserRole).toInt(); paintArea-setPen(QPen(color,value,style,cap,join);,6.2.3 主窗口的实现,ShowPenCap()槽函数的具体实现代码如下:void MainWidget:ShowPenCap(int capValue) QColor color = penColorFrame-palette().color(QPalette:Window); int value = penWidthSpinBox-value(); Qt:PenStyle style = Qt:PenStyle(penStyleComboBox-itemData( penStyleComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenCapStyle cap = Qt:PenCapStyle(penCapComboBox-itemData( capValue,Qt:UserRole).toInt(); Qt:PenJoinStyle join=Qt:PenJoinStyle(penJoinComboBox-itemData( penJoinComboBox-currentIndex(),Qt:UserRole).toInt(); paintArea-setPen(QPen(color,value,style,cap,join);,6.2.3 主窗口的实现,ShowPenJoin()槽函数的具体实现代码如下:void MainWidget:ShowPenJoin(int joinValue) QColor color = penColorFrame-palette().color(QPalette:Window); int value = penWidthSpinBox-value(); Qt:PenStyle style = Qt:PenStyle(penStyleComboBox-itemData( penStyleComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenCapStyle cap = Qt:PenCapStyle(penCapComboBox-itemData( penCapComboBox-currentIndex(),Qt:UserRole).toInt(); Qt:PenJoinStyle join=Qt:PenJoinStyle(penJoinComboBox-itemData( joinValue,Qt:UserRole).toInt(); paintArea-setPen(QPen(color,value,style,cap,join);,6.2.3 主窗口的实现,ShowFillRule()槽函数的具体实现代码如下:void MainWidget:ShowFillRule() Qt:FillRule rule = Qt:FillRule(fillRuleComboBox-itemData( fillRuleComboBox-currentIndex(),Qt:UserRole).toInt(); paintArea-setFillRule(rule);ShowSpreadStyle()槽函数的具体实现代码如下:void MainWidget:ShowSpreadStyle() spread = QGradient:Spread(spreadComboBox-itemData( spreadComboBox-currentIndex(),Qt:UserRole).toInt();,6.2.3 主窗口的实现,ShowBrushColor()槽函数,与设置画笔颜色函数类似,但选定颜色后并不直接调用PaintArea对象的setBrush()函数,而是调用ShowBrush()函数设置显示区的画刷属性,具体实现代码如下:void MainWidget:ShowBrushColor() QColor color = QColorDialog:getColor(static_cast(Qt:blue); brushColorFrame-setPalette(QPalette(color); ShowBrush(brushStyleComboBox-currentIndex();ShowBrush ()槽函数的具体实现代码。,6.2.3 主窗口的实现,其中, QColor color = brushColorFrame-palette().color(QPalette:Window):获得画刷的颜色。 Qt:BrushStyle style = Qt:BrushStyle(brushStyleComboBox-itemData(value, Qt:UserRole).toInt():获得所选的画刷风格,若选择的是渐变或者纹理图案,则需要进行一定的处理。 主窗口的style变量值为Qt: LinearGradientPattern时,表明选择的是线形渐变。 主窗口的style变量值为Qt: RadialGradientPattern时,表明选择的是圆形渐变。 主窗口的style变量值为Qt: ConicalGradientPattern时,表明选择的是锥形渐变。,6.2.3 主窗口的实现,QConicalGradient conicalGradient(startPoint,-(180*angle)/PI)创建锥形渐变类对象需要两个参数,分别是锥形的顶点位置和渐变分界线与水平方向的夹角,如图6.16所示。,6.2.3 主窗口的实现,打开“main.cpp”文件,添加如下代码:#include mainwidget.h#include #include int main(int argc, char *argv) QApplication a(argc, argv); QFont f(ZYSong18030,12); a.setFont(f); MainWidget w; w.show(); return a.exec();,6.2.3 主窗口的实现,运行程序,程序显示效果如图6.17所示。,6.3 Qt 5双缓冲机制,6.3.1 原理与设计本例实现的是一个简单的绘图工具,可以选择线型、线宽及颜色等基本要素,如图6.18所示。,6.3.1 原理与设计,QMainWindow对象作为主窗口,QToolBar对象作为工具栏,QWidget对象作为主窗口的中央窗体centralWidget,也就是绘图区,如图6.19所示。,6.3.2 绘图区的实现,(1)打开“drawwidget.h”头文件,添加的代码。(2)打开“drawwidget.cpp”文件,DrawWidget构造函数完成对窗体参数及部分功能的初始化工作,具体代码如下:#include drawwidget.h #include #include DrawWidget:DrawWidget(QWidget *parent) : QWidget(parent) setAutoFillBackground(true); /对窗体背景色的设置 setPalette(QPalette(Qt:white); pix =new QPixmap(size(); /此QPixmap对象用来准备随时接收绘制的内容 pix-fill(Qt:white); /填充背景色为白色 setMinimumSize(600,400); /设置绘制区窗体的最小尺寸,6.3.2 绘图区的实现,setStyle()函数接收主窗体传来的线型风格参数,setWidth()函数接收主窗体传来的线宽参数值,setColor()函数接收主窗体传来的画笔颜色值。具体代码如下:void DrawWidget:setStyle(int s) style = s;void DrawWidget:setWidth(int w) weight = w;void DrawWidget:setColor(QColor c) color = c;,6.3.2 绘图区的实现,在此事件处理函数中,完成向QPixmap对象中绘图的工作。具体代码如下:void DrawWidget:mouseMoveEvent(QMouseEvent *e) QPainter *painter = new QPainter; QPen pen; pen.setStyle(Qt:PenStyle)style); pen.setWidth(weight); pen.setColor(color); painter-begin(pix); painter-setPen(pen); painter-drawLine(startPos,e-pos(); painter-end(); startPos =e-pos(); update();,6.3.3 主窗口的实现,(1)打开“mainwindow.h”文件,添加代码。(2)打开“mainwindow.cpp”文件,MainWindow类的构造函数完成初始化工作,各个功能见注释说明,具体代码如下:#include mainwindow.h#include #include MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent) drawWidget =new DrawWidget; /新建一个DrawWidget对象 setCentralWidget(drawWidget);/新建的DrawWidget对象作为主窗口的中央窗体 createToolBar(); /实现一个工具栏 setMinimumSize(600,400); /设置主窗口的最小尺寸 ShowStyle(); /初始化线型,设置控件中的当前值作为初始值 drawWidget-setWidth(widthSpinBox-value(); /初始化线宽 drawWidget-setColor(Qt:black); /初始化颜色,6.3.3 主窗口的实现,createToolBar()函数完成工具栏的创建。改变线型参数的槽函数ShowStyle(),通过调用DrawWidget类的setStyle()函数将当前线型选择控件中的线型参数传给绘制区;设置画笔颜色的槽函数ShowColor(),通过调用DrawWidget类的setColor()函数将用户在标准颜色对话框中选择的颜色值传给绘制区。这两个函数的具体代码如下:void MainWindow:ShowStyle() drawWidget-setStyle(styleComboBox-itemData( styleComboBox-currentIndex(),Qt:UserRole).toInt();void MainWindow:ShowColor() QColor color = QColorDialog:getColor(static_cast(Qt:black), this);/使用标准颜色对话框QColorDialog获得一个颜色值 if(color.isValid() drawWidget-setColor(color); QPixmap p(20,20); p.fill(color); colorBtn-setIcon(QIcon(p); ,6.3.3 主窗口的实现,(3)打开“main.cpp”文件,添加如下代码:#include int main(int argc, char *argv) QApplication a(argc, argv); QFont font(ZYSong18030,12); a.setFont(font); MainWindow w; w.show(); return a.exec();(4)运行程序,显示效果如图6.18所示。,6.4 Qt 5 SVG格式图片的显示,SVG格式的特点如下。(1)基于XML。(2)采用文本来描述对象。(3)具有交互性和动态性。(4)完全支持DOM。,6.4 Qt 5 SVG格式图片的显示,下面通过利用QSvgWidget类和QSvgRender类实现一个SVG图片浏览器,显示以“.svg”结尾的文件以介绍SVG格式图片显示的方法,如图6.20所示。,6.4 Qt 5 SVG格式图片的显示,此实例由三个层次的窗体构成,如图6.21所示。,6.4 Qt 5 SVG格式图片的显示,在完成此功能的程序中使用与SVG相关的类,必须在程序中包含SVG相关的头文件:#include 由于Qt默认生成的Makefile中只加入了QtGui、QtCore模块的库,所以必须在工程文件“.pro”中加入一行代码:QT += svg,