Qt实现3D饼图

实现思路:采取画多个圆进行叠加实现3D的效果(参考另外的一个博客内容,忘记具体是哪个了难过)。

效果1:

代码实现:

void CPieWidget::drawDefault3DPie( QPainter *painter )
{
	qreal sum = getSumValue();
	int radius = m_radius; //直径
	//QRect rect = m_pierect;//(w/2-radius/2,h/2-radius/2,radius,radius);

	painter->save();
	QPoint centerp = m_pierect.center();

	QTransform tr;
	tr.translate(centerp.x(),centerp.y());
	tr.rotate(-20,Qt::ZAxis);
	tr.rotate(0,Qt::YAxis);

	painter->setTransform(tr);
	QRect rect(-radius/2,-radius/2,radius,radius);

	//画底图
	int dep = 20/*radius/30*/;
	QPen pen;
	pen.setWidthF(0.2);
	painter->setPen(pen);
	//painter->setPen(Qt::NoPen);
	QStringList keylist = m_datamap.keys();
	for (int j = 0 ; j < dep; ++j)
	{
		qreal index = 30;  //启始位置
		int colorindex = 0;
		for (int i = 0; i < keylist.count(); ++i)
		{
			qreal v = m_datamap.value(keylist.at(i));
			v =v/sum*(360);
			QRect newrect = rect;
			if (m_explodedindex == i || m_isexploded)
			{
				QPoint newcenter = newrect.center();
				int midangel = index+v/2;
				QPoint tp = getMovePoint(midangel);
				newcenter += tp;
				newrect.moveCenter(newcenter);
			}
			QPoint cp = newrect.center() + QPoint(j/2,-j);
			newrect.moveCenter(cp);

			QPoint centerPoint = newrect.center();
			QColor firstColor = m_colorlist.at(colorindex);
			QRadialGradient firstGradient(centerPoint, radius/2);
			if (j == 19)
			{
				firstGradient.setColorAt(0, firstColor.lighter(120));
				firstGradient.setColorAt(1.0, firstColor.lighter(100));
			}
			else
				firstGradient.setColorAt(1.0, firstColor.dark(150));
			painter->setBrush(firstGradient);

			painter->drawPie(newrect, index * 16, v * 16);
			index+=v;		
			colorindex++;
			if (colorindex==m_colorlist.count())
			{
				colorindex = 0;
			}
		}
	}	
	painter->restore();

	
}


效果2:

代码如下:

void CPieWidget::drawDount3DPie( QPainter *painter )
{
	qreal sum = getSumValue();
	int radius = m_radius; //直径
	QPoint centerp = m_pierect.center();

	painter->save();
	QTransform tr;
	tr.translate(centerp.x(),centerp.y());
	tr.rotate(-20,Qt::ZAxis);
	tr.rotate(0,Qt::YAxis);

	painter->setTransform(tr);
	//QRect rect(w/2-radius/2,h/2-radius/2,radius,radius);
	QRect rect(-radius/2,-radius/2,radius,radius);

	//画底图
	int dep = 20/*radius/30*/;
	QPen pen;
	pen.setWidthF(0.2);
	painter->setPen(pen);
	painter->setPen(Qt::NoPen);
	QStringList keylist = m_datamap.keys();
	for (int j = 0 ; j < dep; ++j)
	{
		qreal index = 30;  //启始位置
		int colorindex = 0;
		for (int i = 0; i < keylist.count(); ++i)
		{
			qreal v = m_datamap.value(keylist.at(i));
			v =v/sum*(360);
			QRect newrect = rect;
			if (m_explodedindex == i || m_isexploded)
			{
				QPoint newcenter = newrect.center();
				int midangel = index+v/2;
				QPoint tp = getMovePoint(midangel);
				newcenter += tp;
				newrect.moveCenter(newcenter);
			}
			QPoint cp = newrect.center() + QPoint(j/2,-j);
			newrect.moveCenter(cp);

			QPoint centerPoint = newrect.center();
			QColor firstColor = m_colorlist.at(colorindex);
			QRadialGradient firstGradient(centerPoint, radius/2);
			firstGradient.setColorAt(0, Qt::transparent);
			firstGradient.setColorAt(0.6, Qt::transparent);
			if (j == 19)
			{
				firstGradient.setColorAt(0.61, firstColor.lighter(120));
				firstGradient.setColorAt(1.0, firstColor.lighter(100));
			}
			else
			{
				firstGradient.setColorAt(0.61, firstColor.dark(120));
				firstGradient.setColorAt(1.0, firstColor.dark(150));
			}
			painter->setBrush(firstGradient);

			painter->drawPie(newrect, index * 16, v * 16);
			index+=v;		
			colorindex++;
			if (colorindex==m_colorlist.count())
			{
				colorindex = 0;
			}
		}
	}	
	painter->restore();
}

相关变量说明

QHash<QString,float> m_datamap;
QList<QColor> m_colorlist;

QRect m_pierect;
QRect m_legendrect;
int m_radius;


///

这种方式实现可能会影响效率,因为循环画了多次。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值