




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
8-1 用QPainter绘图(Painting with QPainter)2011-10-26 19:56:04|分类: 默认分类 |标签: |字号大中小订阅 8-1 用QPainter绘图(Painting with QPainter) 分类: C+ GUI Programming with Qt 4 2007-05-29 21:52 8228人阅读 评论(3) 收藏 举报 要在绘图设备(paint device,一般是一个控件)上开始绘制,我们只要创建一个QPainter,把绘图设备指针传给QPainter对象。例如:oid MyWidget:paintEvent(QPaintEvent *event) QPainter painter(this); .使用QPainter的draw()函数我们可以绘制各种图形。图8.1给出了主要的一些。绘制的方式由QPainter的设置决定。设置的一部分是从绘图设备得到的,其他是初始化时的默认值。三个主要的设置为:画笔,刷子和字体。画笔用来绘制直线和图形的边框。包含颜色,宽度,线型,角设置和连接设置。刷子是填充几何图形的方式。包含颜色,方式设置,也可以是一个位图或者渐变色。字体用来绘制文本。字体的属性很多,如字体名,字号等。 这些设置随时可以改变,可用QPen,QBrush,QFont对象调用setPen(),setBrush(),setFont()修改。 Figure 8.1. QPainters most frequently used draw.() functionsFigure 8.2. Cap and join stylesFigure 8.3. Pen stylesFigure 8.4. Predefined brush styles 现在来看看具体的例子。下面的代码是绘制图8.5(a)中椭圆的代码:QPainter painter(this);painter.setRenderHint(QPainter:Antialiasing, true);painter.setPen(QPen(Qt:black, 12, Qt:DashDotLine, Qt:RoundCap);painter.setBrush(QBrush(Qt:green, Qt:SolidPattern);painter.drawEllipse(80, 80, 400, 240);调用函数setRenderHint(QPainter:Antialiasing,true),使绘制时边缘平滑,使用颜色浓度的变化,把图形的边缘转换为象素时引起的扭曲变形尽可能减少,在支持这一功能的平台或者绘图设备上得到一个平滑的边缘。Figure 8.5. Geometric shape examples 下面的代码是图8.5(b)中绘制扇形的代码:QPainter painter(this);painter.setRenderHint(QPainter:Antialiasing, true);painter.setPen(QPen(Qt:black, 15, Qt:SolidLine, Qt:RoundCap, Qt:MiterJoin);painter.setBrush(QBrush(Qt:blue, Qt:DiagCrossPattern);painter.drawPie(80, 80, 400, 240, 60 * 16, 270 * 16);函数drawPie()的最后两个参数值的单位为一度的十六分之一。下面的代码是图8.5(c)中绘制贝赛尔曲线的代码:QPainter painter(this);painter.setRenderHint(QPainter:Antialiasing, true);QPainterPath path;path.moveTo(80, 320);path.cubicTo(200, 80, 320, 80, 480, 320);painter.setPen(QPen(Qt:black, 8);painter.drawPath(path);通过连接基本图形元素,直线,椭圆,多段线,圆弧,二次和三次贝塞尔曲线等,QPainterPath类能确定任何矢量图形。因此,绘图路径(Painter paths)是最基本的绘制元素,任何图形和图形的组合都可以同路径(path)表示。一个路径能够确定一个轮廓,由这个轮廓确定的区域可以由刷子来填充。在图8.5(c)中我们没有设置刷子,因此只绘制了轮廓。以上的三个例子都是使用了默认的刷子(Qt:SolidePattern,Qt:DiagCrossPattern,Qt:NoBrush)。在现在的应用程序中,单色填充已经很少使用,渐变色填充开始收到欢迎。渐变是依靠颜色的变化实现两种或者多种颜色之间平滑的过渡。渐变通常用来处理3D效果,如使用Plastique渐变方式来表现QPushButtons。Qt支持三种类型的渐变:线形渐变,圆锥渐变和圆形渐变(linear, conical, and radial)。下一节的OvenTimer例子就是在一个控件中使用了所有这三种渐变。线形渐变由两个控制点和直线上的一系列颜色点组成。图8.6由下面的代码得到:在两个控制点之间,在三个不同的位置确定了三个不同的颜色值。位置有0到1的浮点数得到,0为第一个控制点,1为第二个控制点。不同位置点之间的颜色由差值计算得到。LinearGradient gradient(50, 100, 300, 350);gradient.setColorAt(0.0, Qt:white);gradient.setColorAt(0.2, Qt:green);gradient.setColorAt(1.0, Qt:black);Figure 8.6. QPainters gradient brushes 圆形渐变由颜色组,圆心(xc,yc),半径r和焦点(xf,yf)定义。圆心和半径定义一个圆,颜色从焦点开始扩散到周围,焦点可以是圆心也可以是圆内的任意一个点。圆锥渐变由圆心(xc,yc)和一个角度a定义。颜色从圆心开始像表的秒针一样扩散。我们已经提到了QPainter的画笔,刷子和字体设置。此外,QPainter还有其他一些设置影响图形和文字的绘制:1. 背景刷子,当背景模式为Qt:OpaqueMode(缺省值为Qt:transparentMode)时,背景刷子用来填充几何图形,文字,和位图的背景(在绘图刷子的下面)2. 刷子的起点:刷子的起始绘制点,通常为控件的左上角。3. 剪辑区域,剪辑区域为绘图设备上可以绘制的区域,在剪辑区域意外进行的绘制是无效的。4. 视口,窗口,世界坐标:这三个决定了QPainter的逻辑坐标映射到物理坐标的方式。通常,逻辑坐标和物理坐标是重合的。坐标系统在下一节介绍。5. 组合方式:组合方式决定绘制设备上新绘制的象素和已经存在的象素的影响方式。缺省方式为覆盖式(source over),新象素画在已有元素的上面。只是有限一个绘图设备支持组合方式的设置,将在本章后面介绍在任何时候,我们可以调用save()把QPainter当前的设置保存在一个内部栈里,然后调用restore()进行恢复。我们能够临时改变QPainter的一些设置,然后恢复先前的值Qt的二位图形引擎是基于 QPainter 类的。它既可以绘制几何形状,也可以绘制像素映射、图像和文字。自定义窗口部件需要重新实现 QWidget:paintEvent() 。 void Widget: paintEvent( QPaintEvent * /*paintEvent*/ ) draw(); drawBezier(); void Widget: draw() QPainter painter( this ); painter. setPen( QPen ( Qt : black, 10 , Qt : DashDotLine, Qt : RoundCap); painter. setBrush( QBrush ( Qt : green, Qt : SolidPattern); painter. drawEllipse( 10 , 10 , 400 , 240 ); painter. drawRect( QRect ( 10 , 300 , 400 , 140 ); 首先需要创建一个 QPainter ,将需要绘图的设备的指针传递给 QPainter 。 QPainter 有各种 draw() 可以绘制不同的图形。画笔、画刷、字体是最重要的三种设置。 画笔用来画线和边缘, QPainter :setPen() 可以对画笔进行设置,包括颜色、宽度、线型、拐点风格等。 画刷用来填充几何形状的图案, QPainter :setBrush() 可以对画刷进行设置,包括颜色和纹理风格。 绘制文本时需要对字体进行设置, QPainter :setFont() 对字体进行设置,包括字体族和磅值。 void Widget: drawBezier() QPainter painter( this ); painter. setRenderHint( QPainter : Antialiasing, true ); QPainterPath path; path. moveTo( 10 , 320 ); path. cubicTo( 200 , 80 , 400 , 80 , 480 , 320 ); painter. setPen( QPen ( Qt : black, 8 ); painter. setBrush( QBrush ( Qt : green, Qt : DiagCrossPattern); painter. drawPath( path); QPainterPath 可以通过连接基本的图形单元元素来确定任意的矢量形状,包括:直线、椭圆、多边形、弧形、贝赛尔曲线等。 首先使用 QPainter :moveto() 来确定图形的起点,然后通过 cubicTo() 来确定绘制的线路。前 4 个参数确定了两个控制点,后两个参数是结束点的位置。 修改函数如下: void Widget: drawBezier() QPainter painter( this ); painter. setRenderHint( QPainter : Antialiasing, true ); QPainterPath path; path. moveTo( 10 , 320 ); path. cubicTo( 200 , 80 , 400 , 80 , 480 , 320 ); painter. setPen( QPen ( Qt : black, 2 ); painter. drawPath( path); painter. setPen( QPen ( Qt : red, 4 ); painter. drawPoint( 10 , 320 ); painter. drawPoint( 200 , 80 ); painter. drawPoint( 400 , 80 ); painter. drawPoint( 480 , 320 ); 画笔样式 为了尝试画笔的样式,这里故意使用了一个新的画笔: painter.setPen(QPen(Qt:black, 5, Qt:DashDotLine, Qt:RoundCap); 我们对照着API去看,第一个参数是画笔颜色,这里设置为黑色;第二个参数是画笔的粗细,这里是5px;第三个是画笔样式,我们使用了 DashDotLine,正如同其名字所示,是一个短线和一个点相间的类型;第四个是RoundCap,也就是圆形笔帽。然后我们使用一个黄色的画刷填充,画了一个椭圆。后面的一个和前面的十分相似,唯一的区别是多了一句 painter.setRenderHint(QPainter:Antialiasing, true); 不过这句也很清楚,就是设置Antialiasing属性为true.如果你学过图形学就会知道,这个长长的单词就是反走样.经过这句设置,我们就打开了QPainter的反走样功能。还记得我们曾经说过,QPainter是一个状态机,因此,只要这里我们打开了它,之后所有的代码都会是反走样绘制的了。 看到这里你会发现,反走样的效果其实比不走样要好得多,那么,为什么不默认打开反走样呢?这是因为,反走样是一种比较复杂的算法,在一些对图像质量要求不高的应用中,是不需要进行反走样的。为了提高效率,一般的图形绘制系统,如Java2D、OpenGL之类都是默认不进行反走样的。 还有一个疑问,既然反走样比不反走样的图像质量高很多,不进行反走样的绘制还有什么作用呢?前面说的是一个方面,也就是,在一些对图像质量要求不高的环境下,或者说性能受限的环境下,比如嵌入式和手机环境,是不必须要进行反走样的。另外还有一点,在一些必须精确操作像素的应用中,也是不能进行反走样的。请看下面的图片: 上图是使用Photoshop的铅笔和画笔工具画的1像素的点在放大到3200%视图下截下来的。Photoshop里面的铅笔工具是不进行反走样,而画笔是要进行反走样的。在放大的情况下就会知道,有反走样的情况下是不能进行精确到1像素的操作的。因为反走样很难让你控制到1个像素。这不是 Photoshop画笔工具的缺陷,而是反走样算法的问题。如果你想了解为什么这样,请查阅计算机图形学里面关于反走样的原理部分。反走样是图形学中的重要概念,用以防止“锯齿”现象的出现。很多系统的绘图API里面都会内置了反走样的算法,不过默认一般都是关闭的,Qt也不例外。下面我们来看看代码。这段代码仅仅给出了paintEvent函数,相信你可以很轻松地替换掉前面章节中的相关代码。voidPaintedWidget:paintEvent(QPaintEvent*event)QPainterpainter(this);painter.setPen(QPen(Qt:black,5,Qt:DashDotLine,Qt:RoundCap);painter.setBrush(Qt:yellow);painter.drawEllipse(50,150,200,150);painter.setRenderHint(QPainter:Antialiasing,true);painter.setPen(QPen(Qt:black,5,Qt:DashDotLine,Qt:RoundCap);painter.setBrush(Qt:yellow);painter.drawEllipse(300,150,200,150);声明:本文原创于yafeilinux的百度博客,/yafeilinux转载请注明出处。前面一节我们讲解了图片的显示,其中很多都用到了坐标的变化,这一节我们简单讲一下Qt的坐标系统,其实也还是主要讲上一节的那几个函数。这里我们先讲解一下Qt的坐标系,然后讲解那几个函数,它们分别是:translate()函数,进行平移变换;scale()函数,进行比例变换;rotate()函数,进行旋转变换;shear()函数,进行扭曲变换。最后介绍两个有用的函数save()和restore(),利用它们来保存和弹出坐标系的状态,从而实现快速利用几个变换来绘图。一、坐标系简介。Qt中每一个窗口都有一个坐标系,默认的,窗口左上角为坐标原点,然后水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,然后以像素为单位增减。例如:void Dialog:paintEvent(QPaintEvent *) QPainter painter(this); painter.setBrush(Qt:red); painter.drawRect(0,0,100,100); painter.setBrush(Qt:yellow); painter.drawRect(-50,-50,100,100);我们先在原点(0,0)绘制了一个长宽都是100像素的红色矩形,又在(-50,-50)点绘制了一个同样大小的黄色矩形。可以看到,我们只能看到黄色矩形的一部分。效果如下图。二、坐标系变换。坐标系变换是利用变换矩阵来进行的,我们可以利用QTransform类来设置变换矩阵,因为一般我们不需要进行更改,所以这里不在涉及。下面我们只是对坐标系的平移,缩放,旋转,扭曲等应用进行介绍。1.利用translate()函数进行平移变换。void Dialog:paintEvent(QPaintEvent *) QPainter painter(this); painter.setBrush(Qt:yellow); painter.drawRect(0,0,50,50);painter.translate(100,100);/将点(100,100)设为原点 painter.setBrush(Qt:red); painter.drawRect(0,0,50,50); painter.translate(-100,-100); painter.drawLine(0,0,20,20);效果如下。这里将(100,100)点作为了原点,所以此时(100,100)就是(0,0)点,以前的(0,0)点就是(-100,-100)点。要想使原来的(0,0)点重新成为原点,就是将(-100,-100)设为原点。2.利用scale()函数进行比例变换,实现缩放效果。void Dialog:paintEvent(QPaintEvent *) QPainter painter(this); painter.setBrush(Qt:yellow); painter.drawRect(0,0,100,100);painter.scale(2,2);/放大两倍 painter.setBrush(Qt:red); painter.drawRect(50,50,50,50);效果如下。可以看到,painter.scale(2,2),是将横纵坐标都扩大了两倍,现在的(50,50)点就相当于以前的(100,100)点。3.利用shear()函数就行扭曲变换。void Dialog:paintEvent(QPaintEvent *) QPainter painter(this); painter.setBrush(Qt:yellow); painter.drawRect(0,0,50,50);painter.shear(0,1);/纵向扭曲变形 painter.setBrush(Qt:red); painter.drawRect(50,0,50,50);效果如下。这里,painter.shear(0,1),是对纵向进行扭曲,0表示不扭曲,当将第一个0更改时就会对横行进行扭曲,关于扭曲变换到底是什么效果,你观察一下是很容易发现的。4.利用rotate()函数进行比例变换,实现缩放效果。void Dialog:paintEvent(QPaintEvent *) QPainter painter(this); painter.drawLine(0,0,100,0);painter.rotate(30);/以原点为中心,顺时针旋转30度 painter.drawLine(0,0,100,0); painter.translate(100,100);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农业保险市场发展态势与风险控制策略报告
- 英利新材料安全知识培训课件
- 园区物业服务培训课件
- 2025年新能源汽车电池包技术创新空间利用效率提升应用场景报告
- 2025副高卫生专业技术资格考试放射卫生(副高)试题及答案解析
- 农村一二三产业融合中的农村医疗保健服务与公共卫生体系建设案例报告
- 2025年餐饮服务流程规范试题解析与答案
- 2025年自然灾害应急救援安全教育培训考试试题及答案解析
- 2024年体育教师专业知识考试题库及答案
- 策划书商业模式
- 中华护理学术会议收获
- 跨境电商风险管理-洞察阐释
- 教师数字提升培训课件
- 中西医结合医院“十五五”发展规划
- 消化性溃疡疾病的护理
- 2025-2030年中国少儿期刊出版行业市场深度调研及前景趋势与投资研究报告
- 2025年河南开封水务投资集团有限公司招聘笔试参考题库含答案解析
- JG/T 220-2007铜铝复合柱翼型散热器
- T/CCAA 39-2022碳管理体系要求
- 江苏省扬州市广陵区梅岭中学2025届七下数学期末综合测试模拟试题含解析
- 2025年浙江省公务员录用考试《行测》真题及答案解析(B类)
评论
0/150
提交评论