不规则图形的渐变填充"/>
【毕设笔记】Qt不规则图形的渐变填充
毕设笔记——Qt不规则图形的渐变填充
- 需求说明
- 实现方法
- 关键类的认识
- QPainterPath
- 简介
- moveTo函数
- actTo函数
- lineTo
- QLinearGradient
- 简介
- setColorAt函数
- 踩坑过程
- 盲目抄手册
- 没有指定渐变类的起始点与终点
- 乱用moveTo函数
- 最终结果与代码
- 无源振子
- 有源振子
需求说明
最近写毕设时,需要利用Qt实现一个引向天线设计优化的软件,最近刚把计算模型搭建完毕,准备开始GUI界面设计。我的计划是先从天线的示意图开始做起,从一本天线英文书看到的示意图还不错,准备用Qt场景图元实现之,这样也方便用户添加与删除振子。
实现方法
关键类的认识
QPainterPath
简介
从描述中可以看到,一个QPainterPath可以看成是存放一些图形单元的容器,可以是线,椭圆最关键的是,他能用于填充,这是完成本需求的关键之一。
moveTo函数
这个函数形象地说,就是假设你手上拿着一支笔,你要从哪一点开始画起,但请注意他的说明:closing the previous one,也就是说,你如果前面添加的不是闭合曲线,该函数会将其闭合,比如你画了一个段弧,起始点为(x1,y1),终点为(x2,y2),你最后画完了调用moveTo(x1,y1)从终点回到起点,该函数会在(x1,y1)和(x2,y2)之间连一条直线使其闭合。
actTo函数
这是一个往QPainterPath添加圆弧的函数,参数分别为弧的外接矩形,开始角度,扫过的角度
lineTo
连线功能,连接当前点和指定的结束点。
注意:QPainterPath当前点是一直在变化的。假设你有一只笔,你画一条直线,你笔现在的所在位置就是QPainterPath的当前点
QLinearGradient
简介
渐变主要是通过该类实现的,可以从中看到,PadSpread方式和ReflectSpread方式都是可以实现该效果的。
通过该描述可以知道,我们可以通过SetColorAt函数添加一些点的颜色,该类会实现你指定的两点(两种颜色)之间的渐变效果。
setColorAt函数
position参数相当于归一化处理,0为起始点,1为结束点,比如0.5为中间点,我们也可以添加很多个中间点(取值为0-1),插入很多个颜色。就拿我们要实现的需求来说,我们要实现从灰->白->灰这样的效果,我添加的三个点为(0,灰色)、(0.7,白色)、(1,灰色)
踩坑过程
盲目抄手册
看到手册那个arcTo函数的用法举例后,我以为要先调用moveTo把当前点移动到椭圆中心点,最后画出的图像是
中间多出来了一条线,搜了其他人的博客才发现这个问题
没有指定渐变类的起始点与终点
我直接用
没有参数的构造函数(因为前面手册也没有参数),导致我的柱子依然是白色的,没有渐变色。仔细看了一下手册才发现需要指定起始点和终点,这样子就是指定了渐变的方向,从起始点——>终点
乱用moveTo函数
没有看到moveTo的后半段说明,画一段调用一次moveTo,导致画出来的图像很不对
注意往QPainterPath添加曲线时,一定要想象你如何一口气画完不规则曲线,而不要中间使用moveTo
最终结果与代码
无源振子
/** 功能:绘制一根天线* 参数:天线的中心点,天线的长度,天线的半径*** */
void Widget::drawAntPassive(QPointF center, qreal length,qreal radius)
{QPainter pr(this);pr.setRenderHint(QPainter::Antialiasing, true);//打开反走样QPen pen;pen.setWidthF(3); //画笔相关pr.setPen(pen);QRectF rect(QPointF(center.x()-radius,center.y()-length-radius/2),QPointF(center.x()+radius,center.y()-length+radius/2)); //顶部椭圆外接矩形QRectF rect2(QPointF(center.x()-radius,center.y()+length-radius/2),QPointF(center.x()+radius,center.y()+length+radius/2));//绘制棍子底部弧所需外接矩形pr.drawArc(rect,0,180*16); //绘制棍子顶部椭圆的半圆,仿三维,因为顶部椭圆无色,接下去要用QPointerPathQPainterPath myPath;//这里画待填充渐变的区域,注意中间不要使用moveTomyPath.moveTo(center.x()-radius,center.y()-length);myPath.arcTo(rect,180.0f,180.0f); //绘制上椭圆下半圆myPath.lineTo(QPointF(center.x()+radius,center.y()+length)); //右边竖线myPath.arcTo(rect2,0,-180.0f);myPath.lineTo(QPointF(center.x()-radius,center.y()-length)); //左边竖线QLinearGradient myGradient(QPointF(center.x()-radius,center.y()),QPointF(center.x()+radius,center.y()));//一定要指定开始点和结束点,标明绘制的方向,才能正常绘制渐变,这是我踩的一个坑//仿三维,渐变色//myGradient.setSpread(QGradient::ReflectSpread);myGradient.setColorAt(0,QColor(QString("#474747")));myGradient.setColorAt(0.7,QColor(QString("#FFFFFF")));myGradient.setColorAt(1,QColor(QString("#878787")));QBrush brh(myGradient);pr.setBrush(brh);pr.drawPath(myPath);
}
有源振子
有源振子只要在无源振子下加画一个源即可。代码如下
/*** @brief Widget::drawAntActive* @param center 天线的中点* @param length 天线的长度* @param radius 天线的半径*/
void Widget::drawAntActive(QPointF center, qreal length, qreal radius)
{drawAntPassive(center,length,radius);//以下为绘制源QPainter pr(this);pr.setRenderHint(QPainter::Antialiasing, true);//打开反走样QPen pen;pen.setWidth(3);pr.setPen(pen);pr.setBrush(QBrush(Qt::white));QRectF rect(QPointF(center.x()-2*radius,center.y()-2*radius),QPointF(center.x()+2*radius,center.y()+2*radius)); //外部圆的外接矩形pr.drawEllipse(rect); //源外部圆的绘制QRectF rect2(QPointF(center.x()-radius,center.y()-radius/2),QPointF(center.x(),center.y()+radius/2)); //外接矩形1pr.drawArc(rect2,0,180*16);QRectF rect3(QPointF(center.x(),center.y()-radius/2),QPointF(center.x()+radius,center.y()+radius/2)); //外接矩形2pr.drawArc(rect3,0,-180*16);
}
接下去只需要将这两个函数写进QGraphicsItem的paint虚函数即可
更多推荐
【毕设笔记】Qt不规则图形的渐变填充
发布评论