1.以在UI上添加柱状图的类为例(Histogram)
#ifndef STUDY_HISTOGRAM_H
#define STUDY_HISTOGRAM_H#include <QVector>
#include <QWidget>// 前向声明
QT_BEGIN_NAMESPACE
class QColor;
class QRect;
class QString;
class QPaintDevice;
QT_END_NAMESPACEclass Study_HistogramItem
{
public:QString m_Name;qreal m_Value;QColor m_PillarColor;QRect m_PillarRect;
};class Study_Histogram : public QWidget
{public:Study_Histogram( QWidget* parent = 0 );//方法void Study_AddItem( QString name, qreal value,QColor pillarColor );void Study_SetMaxValue( quint32 maxValue ); // 设置最大值,以便绘图void Study_Clear(); // 清空所有已添加的Itemvoid Study_Paint( QPaintDevice* pDevice ); // 绘图protected://刷新页面void paintEvent(QPaintEvent *);private:void Study_DrawAxis( QPaintDevice* pDevice, QPainter* pPainter ); // 绘制坐标轴void Study_DrawPillars( QPaintDevice* pDevice, QPainter* pPainter ); // 绘制柱子void Study_DrawText( QPainter *pPainter ); // 绘制文字void Study_DrawScale( QPaintDevice* pDevice, QPainter* pPainter ); // 绘制刻度//类属性enum Study_HistogramOptions{blankWidth = 64, // 两个柱子间的空格大小pillarIndent = 0, // 首个柱子缩进的大小xAxisOffset = 16, // X轴的偏移(相对于左边界)yAxisOffset = 16, // Y轴的偏移(相对于下边界)textRectHeight = 32 // 文字矩形框的高};qreal m_Study_axValue;QVector<Study_HistogramItem> m_Study_VecItems;};#endif // STUDY_HISTOGRAM_H
2.饼图的属性:最大值,单个柱形的信息
在饼图类的构造函数中设置默认的信息:清空之前的柱形组数据
Study_Histogram::Study_Histogram(QWidget *parent)
{m_Study_VecItems.clear( );
}
3.饼图的方法(函数):添加柱形,设置最大值,清空信息
添加柱形:
void Study_Histogram::Study_AddItem(QString name, qreal value, QColor pillarColor)
{//先创建一个柱状信息的实例Study_HistogramItem item;item.m_Name = name;item.m_Value = value;item.m_PillarColor = pillarColor;item.m_PillarRect = QRect( );//将此实例添加到属性QVector中m_Study_VecItems.push_back( item );
}
设置最大值:
void Study_Histogram::Study_SetMaxValue(quint32 maxValue)
{//将参数传入类属性中m_Study_maxValue = maxValue;
}
清空信息:
void Study_Histogram::Study_Clear()
{//把柱状图信息容器清空m_Study_VecItems.clear();
}
4.某些属性的关联数据(单个柱形信息包括:名字,数据,颜色等)
在类的定义.h文件中,定义了结构体Study_HistogramItem
供给属性QVector<Study_HistogramItem> m_Study_VecItems;
5.paintEvent进行自动刷新
void Study_Histogram::paintEvent(QPaintEvent *)
{Study_Paint(this);
}void Study_Histogram::Study_Paint(QPaintDevice *pDevice)
{QPainter painter( pDevice ); //Study_DrawAxis( pDevice, &painter );// 绘制坐标轴Study_DrawPillars( pDevice, &painter );// 绘制柱子Study_DrawText( &painter );// 绘制文字Study_DrawScale( pDevice, &painter );// 绘制刻度
}
绘制坐标轴/柱子/文字/刻度(pPainter->drawText)
void Study_Histogram::Study_DrawAxis(QPaintDevice *pDevice, QPainter *pPainter)
{//坐标轴pPainter->drawLine( yAxisOffset, 0, yAxisOffset, pDevice->height( ) );pPainter->drawLine( 0, pDevice->height( ) - xAxisOffset,pDevice->width( ), pDevice->height( ) - xAxisOffset );
}void Study_Histogram::Study_DrawPillars(QPaintDevice *pDevice, QPainter *pPainter)
{//柱子if ( m_Study_VecItems.size( ) == 0 ) return;//const quint32 blankWidth = 64; // 柱子间空格宽quint32 pillarWidth = ( pDevice->width( ) - yAxisOffset - pillarIndent- quint32( m_Study_VecItems.size( ) - 1 ) * blankWidth )/ m_Study_VecItems.size( ); // 柱子的宽// 绘制因子。绘制因子在绘制柱子的时候起着重要作用。// 根据比例公式:// pDevice->width( ) - xAxisOffset pillarHeight// --------------------------------- = --------------------// MaxValue m_VecItem[0].value// 求出pillarHeight的值,但是左边的部分我们可以看作是一个绘制因子heightFact记录下来。// 计算时可以节约时间。qreal heightFact = qreal( pDevice->height( ) - xAxisOffset ) / m_Study_maxValue;for ( int i = 0; i < m_Study_VecItems.size( ); ++i ){quint32 pillarHeight = m_Study_VecItems[i].m_Value * heightFact;int leftUpX = yAxisOffset + pillarIndent + i * ( pillarWidth + blankWidth );int leftUpY = pDevice->height( ) - xAxisOffset - pillarHeight;QRect& rect = m_Study_VecItems[i].m_PillarRect;rect.setRect( leftUpX, leftUpY, pillarWidth, pillarHeight );pPainter->setPen( QPen( m_Study_VecItems[i].m_PillarColor ) );pPainter->setBrush( QBrush( m_Study_VecItems[i].m_PillarColor ) );pPainter->drawRect( rect );}}void Study_Histogram::Study_DrawText(QPainter *pPainter)
{// 已经可以保证m_VecItems.[i].m_Rect.isNull( )为假// 即柱子所在的矩形框是一个有效的矩形框pPainter->setPen( QPen( QColor( 0, 0, 0 ) ) );for ( int i = 0; i < m_Study_VecItems.size( ); ++i ){QRect rect( m_Study_VecItems[i].m_PillarRect.left( ) - blankWidth / 2,m_Study_VecItems[i].m_PillarRect.top( ) - textRectHeight,m_Study_VecItems[i].m_PillarRect.width( ) + blankWidth,textRectHeight );const QString& text = QString( "%1(%2)" ).arg( m_Study_VecItems[i].m_Name ).arg( m_Study_VecItems[i].m_Value );pPainter->drawText( rect, Qt::AlignCenter, text );}
}void Study_Histogram::Study_DrawScale(QPaintDevice *pDevice, QPainter *pPainter)
{// 名词解释 MSWidth = Marked Scale Width,刻度宽// MSHeight = Marked Scale Height 刻度高const quint32 MSWidth = 100;const quint32 MSHeight = textRectHeight;const quint32 heightInterval= ( pDevice->height( ) - xAxisOffset ) / 4;for ( int i = 0; i < 4; ++i ){QRect rect( 0,i * heightInterval,MSWidth,MSHeight );pPainter->drawLine( yAxisOffset - 2,i * heightInterval,yAxisOffset + 2,i * heightInterval );pPainter->drawText(rect, Qt::AlignLeft, QString( "%1" ).arg( m_Study_maxValue * ( 4 - i ) / 4 ) );}
}
使用:直接用ui -> …(提升的UI名) -> 类方法,此处ui->widget_histogram已经在UI中提升为Study_Histogram
ui->widget_histogram->Study_SetMaxValue(100);ui->widget_histogram->Study_AddItem("name1",35,"red");ui->widget_histogram->Study_AddItem("name2",45,"green");ui->widget_histogram->Study_AddItem("name3",55,"black");ui->widget_histogram->Study_AddItem("name4",75,"red");
效果: