Qt开发之QPainter不为人知的秘密

Qt开发之QPainter不为人知的秘密一 开篇 QPainter 在自定义控件中经常使用 文本总结一些在使用过程中的一些关键点 首先介绍一下 QPainter 吧

欢迎大家来到IT世界,在知识的湖畔探索吧!

一、开篇

QPainter在自定义控件中经常使用,文本总结一些在使用过程中的一些关键点。首先介绍一下QPainter吧。如下官方给出的功能解释:The QPainter class performs low-level painting on widgets and other paint devices

从而,我们可以得到几个重要信息:

(1)QPainter是一个底层绘图类,故而常常在自定义的控件中使用。

(2)QPainter的绘制对象是QWidget和绘制设备QPaintDevice。解释一下什么是Qt中的绘制设备:在Qt中,绘制设备是一个二维空间的抽象,可使用QPainter进行绘制。它的默认坐标系统的原点位于左上角,X向右增加,Y向下增加,单位为1个像素。QPaintDevice的绘图功能由QWidget、QImage、QPixmap、QGLPixelBuffer、QPicture和QPrinter子类实现。

总而言之,在创建QPainter示例时,传给QPainter的参数可以是QWidget、QImage、QPixmap、QGLPixelBuffer、QPicture和QPrinter子类等。例如:在定义控件时,我们在paintEvent()函数中创建QPainter时,会传入this参数,那么该参数就代表创建的QPainter的绘制设备是QWidget。

二、QPainter的属性参数

使用QPainter进行自定义绘制时,本质则是:在什么地方,使用指定属性参数的画笔,绘制什么

(2-1)在什么地方

这一点指明QPainter在什么地方进行绘制,这往往由QPainter的坐标或绘制区域指定,默认是左上角为(0,0),向下和向右增加。

(2-2)指定属性参数

这一点指明QPainter绘制时所使用的画笔参数。可以设置QPen、QBrush、QFont、opacity(透明度)等属性参数。这些属性参数则指明使用什么样的QPainter进行绘制。那么接下来就是绘制什么了

(2-3)绘制什么

这一点在QPainter中非常的有规律,凡是以drawXxxx命名的成员函数,都代表绘制的是什么。例如:drawLine()、drawPixmap()、drawText()等,更多的函数可参见官方文档。

三、巧用save()和restore()函数

save和restore两个函数都是QPainter的成员函数,看看官方对其解释:

(1)save():Saves the current painter state (pushes the state onto a stack). A save() must be followed by a corresponding restore()。

(2)restore():Restores the current painter state (pops a saved state off the stack).

总而言之,就是将QPainter的当前状态使用save函数压入堆栈,在一系列绘制后,再使用restore函数从堆栈中恢复QPainter之前的状态。

在实际使用中,绘制往往是一系列绘制步骤的组合,例如有:1、2、3、4、5个绘制步骤。当在绘制完步骤1后,我们接着绘制步骤2,这个时候我们重新设置了QPainter的状态(例如颜色、画笔宽度等),紧接着绘制步骤3,这个时候我们又重新设置了QPainter的状态,然而在绘制步骤4的时候,其QPainter的状态与步骤2一样,这时候我们不会再去重新设置一下QPainter了吧,这时候就可以在步骤2后使用save保存步骤3的QPainter状态,在绘制步骤3后,使用restore延用步骤2绘制步骤4(从而避免了重复设置QPainter的工作)。

例如,如下代码片段:

void Widget::paintEvent(QPaintEvent * event) { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.translate(this->width()/2,this->height()/2); painter.setPen(QPen(Qt::red,2)); //步骤1:绘制一根红色、2宽度垂直的线 painter.drawLine(10,0,10,100); //步骤2:绘制一根黑色、10宽度的线 painter.setPen(QPen(Qt::black,10)); painter.drawLine(50,0,50,100); //使用save保存步骤2时所使用的QPainter状态 painter.save(); //步骤3:绘制一根黄色、5宽度的线 painter.setPen(QPen(Qt::yellow,5)); painter.drawLine(100,0,100,100); //步骤4:绘制一根和步骤2一样的线 //使用步骤restore恢复步骤2的QPainter状态。而不用重新使用setPen设置QPainter的画笔状态了 painter.restore(); painter.drawLine(150,0,150,100); }

欢迎大家来到IT世界,在知识的湖畔探索吧!

效果:

Qt开发之QPainter不为人知的秘密

欢迎大家来到IT世界,在知识的湖畔探索吧!

(第二根和第四根线样式一样)

四、使用setRenderHints()设置QPainter渲染效果

在开发中,需要使用setRenderHints()函数设置QPainter的渲染效果,如果不适用,绘制出的图形一般会带有锯齿。传入setRenderHints的参数常用的是: (1)QPainter::Antialiasing:指示绘制引擎尽可能消除图形的锯齿边界。

(2)QPainter::SmoothPixmapTransform: 指示绘制引擎使用平滑的像素映射转换算法(如双线性)来进行绘制。

五、QPainter的绘制步骤的顺序很关键

有些时候,适当的调整QPainter的绘制步骤顺序,往往就达到了我们的设计需求,QPainter中没有例如PS图层的概念,在许多以贴图方式实现的控件中,合理的调整QPainter的绘制顺序就变得很关键。

例如:

Qt开发之QPainter不为人知的秘密

在上图中,红色框中代表的是一个可以水平移动的滑动块,其在实际的开发中,该滑动块将在背景图片下进行移动,这是开发的目标效果。其合理的代码如下:

欢迎大家来到IT世界,在知识的湖畔探索吧!QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing ); painter.setRenderHint(QPainter::SmoothPixmapTransform); QPixmap moveIndicatorPix(":/assets/images_controlPage/moveSlot_832x83.png"); //步骤1:绘制移动块 painter.drawPixmap(movePos,0,moveIndicatorPix); //步骤2:绘制背景 painter.drawPixmap(this->rect(),bgImage); 

效果如下:

Qt开发之QPainter不为人知的秘密

如果将绘制步骤交换一下位置。例如以下代码:

QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing ); painter.setRenderHint(QPainter::SmoothPixmapTransform); QPixmap moveIndicatorPix(":/assets/images_controlPage/moveSlot_832x83.png"); //步骤1:绘制背景 painter.drawPixmap(this->rect(),bgImage); //步骤2:绘制移动块 painter.drawPixmap(movePos,0,moveIndicatorPix);

则变为如下图所示的效果:

Qt开发之QPainter不为人知的秘密

可见,第一种效果才是预期的效果。

综上,可见QPainter的绘制步骤在实际的开发中非常关键。

六、移动QPainter的坐标系,方便绘制

1、在实际开发中,默认QPainter的坐标系以左上角开始,我们可以使用:

欢迎大家来到IT世界,在知识的湖畔探索吧!painter.translate(this->width()/2,this->height()/2);

将坐标系的零点移动到QWidget的中心,这样在进行旋转、缩放绘制操作时较为方便。

2、可以使用setViewport()设置QPainter的视图窗口,默认是整个QWidget。


免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/90013.html

(0)
上一篇 34分钟前
下一篇 12分钟前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信