利用QPainter实现金字塔图,2D和3D效果。如下:
核心代码如下
头文件
#ifndef CPYRAMIDDLG_H
#define CPYRAMIDDLG_H
#include <QWidget>
#include <QPainter>
enum PyramidStyle
{
DefaultPyramid=0,
ShadingPyramid,
ShapePyramid,
Pyramid
};
class CPyramidDlg : public QWidget
{
Q_OBJECT
public:
CPyramidDlg(QObject *parent = NULL);
~CPyramidDlg();
void setLayerCount(int count);
void setPyramidStyleSheet(PyramidStyle pstype);
void setColorList(QList<QColor> colorlist);
void setColor(int index, QColor color);
protected:
void paintEvent(QPaintEvent *e);
private:
void init();
void drawPyramid(QPainter *painter);
void drawDefaultPyramid(QPainter *painter);
void drawShadingPyramid(QPainter *painter);
void drawShapePyramid(QPainter *painter);
private:
QList<QColor> m_colorlist;
int m_layercount; //层数 默认4
PyramidStyle m_pyrstyle;
};
#endif // CPYRAMIDDLG_H
cpp文件
#include “cpyramiddlg.h”
#include
CPyramidDlg::CPyramidDlg(QObject *parent)
{
init();
}
CPyramidDlg::~CPyramidDlg()
{
}
void CPyramidDlg::init()
{
setPyramidStyleSheet(ShapePyramid);
m_colorlist << QColor(255,242,0);
m_colorlist << QColor(141,198,63);
m_colorlist << QColor(251,176,64);
m_colorlist << QColor(146,39,143);
m_colorlist << QColor(136,68,255);
m_colorlist << QColor(102,170,238);
m_colorlist << QColor(238,187,34);
m_layercount = 5;
}
void CPyramidDlg::setLayerCount( int count )
{
if (count > 0)
m_layercount = count;
}
void CPyramidDlg::setPyramidStyleSheet( PyramidStyle pstype )
{
m_pyrstyle = pstype;
}
void CPyramidDlg::setColorList( QList colorlist )
{
m_colorlist.clear();
m_colorlist = colorlist;
}
void CPyramidDlg::setColor( int index, QColor color )
{
if (m_colorlist.count() > index)
m_colorlist.replace(index,color);
else
m_colorlist.append(color);
}
void CPyramidDlg::paintEvent( QPaintEvent *e )
{
QPainter *painter = new QPainter(this);
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->setRenderHint(QPainter::TextAntialiasing);
drawPyramid(painter);
}
void CPyramidDlg::drawPyramid( QPainter *painter )
{
switch (m_pyrstyle)
{
case DefaultPyramid: drawDefaultPyramid(painter); break;
case ShadingPyramid: drawShadingPyramid(painter); break;
case ShapePyramid: drawShapePyramid(painter); break;
default:drawDefaultPyramid(painter);break;
}
}
void CPyramidDlg::drawDefaultPyramid( QPainter *painter )
{
painter->save();
//painter->setPen(Qt::NoPen);
int w = width();
int h = height();
int radia = qMin(w,h)*0.8;
QPoint cerentpoint(w/2,h/2);
QPoint topp(w/2,radia*0.1);
QPoint leftbottom(w/2-radia/2,h-20);
QPoint rigthbottom(w/2+radia/2,h-20);
int hradia = h;
int laycount = m_layercount;
if (laycount < 2)
laycount = 5;
int step = radia/m_layercount/10;
for (int i = 0 ;i < laycount-1; ++i)
{
int indexradia = radia/2*i/laycount;
int hindexradia = hradia*i/laycount;
int indexradia1 = radia/2*(i+1)/laycount;
int hindexradia1 = hradia*(i+1)/laycount;
QPoint p1(topp.x()-indexradia,topp.y()+hindexradia);
QPoint p2(topp.x()+indexradia,topp.y()+hindexradia);
QPoint p3(topp.x()-indexradia1,topp.y()+hindexradia1-step);
QPoint p4(topp.x()+indexradia1,topp.y()+hindexradia1-step);
QPainterPath rectpath;
rectpath.moveTo(p1);
rectpath.lineTo(p2);
rectpath.lineTo(p4);
rectpath.lineTo(p3);
rectpath.lineTo(p1);
QColor color(Qt::blue);
if (i < m_colorlist.count())
{
color = m_colorlist.at(i);
}
QLinearGradient lineGradient(p1, p3);
lineGradient.setColorAt(0, color/*.lighter(120)*/);
//lineGradient.setColorAt(1.0, color/*.lighter(80)*/);
painter->setBrush(lineGradient);
painter->drawPath(rectpath);
}
painter->restore();
}
void CPyramidDlg::drawShadingPyramid( QPainter *painter )
{
painter->save();
//painter->setPen(Qt::NoPen);
int w = width();
int h = height();
int radia = qMin(w,h)*0.8;
QPoint cerentpoint(w/2,h/2);
QPoint topp(w/2,60);
QPoint leftbottom(w/2-radia/2,h-20);
QPoint rigthbottom(w/2+radia/2,h-20);
int hradia = h;
int laycount = m_layercount;
if (laycount < 2)
laycount = 5;
int step = radia/m_layercount/10;
for (int i = 0 ;i < laycount-1; ++i)
{
int indexradia = radia/2*i/laycount;
int hindexradia = hradia*i/laycount;
int indexradia1 = radia/2*(i+1)/laycount;
int hindexradia1 = hradia*(i+1)/laycount;
QPoint p1(topp.x()-indexradia,topp.y()+hindexradia);
QPoint p2(topp.x()+indexradia,topp.y()+hindexradia);
QPoint p3(topp.x()-indexradia1,topp.y()+hindexradia1-step);
QPoint p4(topp.x()+indexradia1,topp.y()+hindexradia1-step);
QPainterPath rectpath;
rectpath.moveTo(p1);
rectpath.lineTo(p2);
rectpath.lineTo(p4);
rectpath.lineTo(p3);
rectpath.lineTo(p1);
QColor color(Qt::blue);
if (i < m_colorlist.count())
{
color = m_colorlist.at(i);
}
QLinearGradient lineGradient(p3, p4);
lineGradient.setColorAt(0, color.lighter(80));
lineGradient.setColorAt(0.48, color.lighter(150));
lineGradient.setColorAt(0.52, color.lighter(150));
lineGradient.setColorAt(1.0, color.lighter(80));
painter->setBrush(lineGradient);
painter->drawPath(rectpath);
}
painter->restore();
}
void CPyramidDlg::drawShapePyramid( QPainter *painter )
{
painter->save();
//painter->setPen(Qt::NoPen);
int w = width();
int h = height();
int radia = qMin(w,h)*0.8;
QPoint cerentpoint(w/2,h/2);
QPoint topp(w/2,radia*0.1);
QPoint leftbottom(w/2-radia/2,h-20);
QPoint rigthbottom(w/2+radia/2,h-20);
int hradia = h;
int laycount = m_layercount;
if (laycount < 2)
laycount = 5;
int step = hradia*0.04;
int length = 10;
for (int i = 0 ;i < laycount-1; ++i)
{
int indexradia = radia/2*i/laycount;
int hindexradia = hradia*i/laycount;
int indexradia1 = radia/2*(i+1)/laycount;
int hindexradia1 = hradia*(i+1)/laycount-step;
QPoint p1(topp.x()-indexradia,topp.y()+hindexradia);
QPoint p2(topp.x()+indexradia,topp.y()+hindexradia);
QPoint p3(topp.x()-indexradia1,topp.y()+hindexradia1);
QPoint p4(topp.x()+indexradia1,topp.y()+hindexradia1);
QPainterPath rectpath;
rectpath.moveTo(p1);
rectpath.lineTo(p2);
rectpath.lineTo(p4);
rectpath.lineTo(p3);
rectpath.lineTo(p1);
QColor color(Qt::blue);
if (i < m_colorlist.count())
{
color = m_colorlist.at(i);
}
QLinearGradient lineGradient(p3, p4);
lineGradient.setColorAt(0, color.dark(100));
// lineGradient.setColorAt(0.48, color.lighter(150));
// lineGradient.setColorAt(0.52, color.lighter(150));
// lineGradient.setColorAt(1.0, color.dark(180));
painter->setBrush(lineGradient);
painter->drawPath(rectpath);
lineGradient.setColorAt(0, color.dark(200));
painter->setBrush(lineGradient);
//上边的部分
QPainterPath toprectpath;
int yL = step*0.2*i;
int xL = step*0.2*i;
QPoint topleft(p1.x()+xL,p1.y()-yL);
QPoint toprigth(p2.x()+xL,p2.y()-yL);
QPoint bottomrigth(p4.x()+xL+step*0.5,p4.y()-yL);
toprectpath.moveTo(p1);
toprectpath.lineTo(topleft);
toprectpath.lineTo(toprigth);
toprectpath.lineTo(p2);
painter->drawPath(toprectpath);
lineGradient.setColorAt(0, color.dark(150));
painter->setBrush(lineGradient);
//右侧部分
QPainterPath rightrectpath;
rightrectpath.moveTo(p2);
rightrectpath.lineTo(p4);
rightrectpath.lineTo(bottomrigth);
rightrectpath.lineTo(toprigth);
painter->drawPath(rightrectpath);
}
painter->restore();
}