欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt实现3D饼图

程序员文章站 2022-07-13 08:28:08
...

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

效果1:

Qt实现3D饼图

代码实现:

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:

Qt实现3D饼图

代码如下:

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;


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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