一、创建项目工程
1、创建qt 工程
2、将下载的QCustomPlot源文件的.c .h文件分别添加到源文件和头文件中
3、在./pro中添加
QT += widgets printsupport
4、在Ui界面中添加一个新的widget控件
右击鼠标选择“提升为”,提升类名称输入“QCustomPlot”,点击添加,点击提升
如图所示
二、主要代码
1、.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QVector>
#include <QString>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//绘制柱状图对象
minBar = new CustomBars (ui->qcustomplot->xAxis,ui->qcustomplot->yAxis);
maxBar = new CustomBars (ui->qcustomplot->xAxis,ui->qcustomplot->yAxis);
fossil = new CustomBars (ui->qcustomplot->xAxis,ui->qcustomplot->yAxis);
initBar();
}
void Widget::initBar()
{
//设置画笔颜色red, green,blue,
minBar->setPen(QPen(Qt::red));
maxBar->setPen(QPen(Qt::green));
fossil->setPen(QPen(Qt::blue));
//设置填充颜色
minBar->setBrush(Qt::red);
maxBar->setBrush(Qt::green);
fossil->setBrush(Qt::blue);
QCPBarsGroup *group = new QCPBarsGroup(ui->qcustomplot);
group->setSpacingType(QCPBarsGroup::stAbsolute); // 设置组内柱状图的间距,按像素
group->setSpacing(0); // 设置较小的间距值,这样看起来更紧凑
fossil->setBarsGroup(group);
maxBar->setBarsGroup(group);
minBar->setBarsGroup(group);
//设置大小
//minBar->setBaseValue(0.5); //设置柱状图距离x轴的距离
//设置柱状图的宽度
minBar->setWidth(0.5);
maxBar->setWidth(0.5);
fossil->setWidth(0.5);
//设置抗锯齿
minBar->setAntialiased(false); // gives more crisp, pixel aligned bar borders
maxBar->setAntialiased(false);
fossil->setAntialiased(false);
addValue();
}
void Widget::addValue()
{
//设置坐标
QVector<double> ticks;
QVector<QString> labels;
//添加元素,将拉大刻度间的间距
int count = 2;
for(int i =1 ;i <20;i++)
{
if(i == count)
{
ticks <<i;
count +=2;
}
}
count = 0;
for(int i =2 ;i <30;i++)
{
if(i == 2+count)
{
labels << QString::number(i,10);
count +=1;
}
}
//共享指针--坐标轴的设置
QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
textTicker->addTicks(ticks, labels);
ui->qcustomplot->plotLayout()->insertRow(0);
//添加x轴
ui->qcustomplot->xAxis->setTicker(textTicker);
//设置标签的旋转
ui->qcustomplot->xAxis->setTickLabelRotation(0);
ui->qcustomplot->xAxis->setSubTicks(false);
//设置刻度线的长度
ui->qcustomplot->xAxis->setTickLength(0, 4);
//设置x轴的范围
ui->qcustomplot->xAxis->setRange(0,20);
//分层设置
ui->qcustomplot->xAxis->grid()->setVisible(false);
ui->qcustomplot->yAxis->grid()->setSubGridVisible(false);
ui->qcustomplot->yAxis->setSubTicks(false);
//设置y轴的范围
ui->qcustomplot->yAxis->setRange(0,15);
QVector<double> y,y1,y2;
y << 9 << 7 << 5 << 2 << 7 << 4 << 9 << 1;
y1 << 1 << 9.03 << 6 << 2 << 7 << 3<< 1 << 9;
y2 << 9.87 << 7 << 5 << 2 << 7.12 << 4 << 9 << 1;
minBar->addData(ticks,y);
maxBar->addData(ticks,y1);
fossil->addData(ticks,y2);
//刷新曲线
ui->qcustomplot->replot();
}
Widget::~Widget()
{
delete ui;
}
2、custombars.cpp文件
#include "custombars.h"
CustomBars::CustomBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
: QCPBars(keyAxis, valueAxis),
mTextAlignment(Qt::AlignCenter),
mSpacing(5),
mFont(QFont(QLatin1String("sans serif"), 12))
{
}
void CustomBars::setTextAlignment(Qt::Alignment alignment)
{
mTextAlignment = alignment;
}
void CustomBars::setSpacing(double spacing)
{
mSpacing = spacing;
}
void CustomBars::setFont(const QFont &font)
{
mFont = font;
}
void CustomBars::draw(QCPPainter *painter)
{
if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
if (mDataContainer->isEmpty()) return;
//定义两个图表数据容器
QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd;
//获取可见数据范围
getVisibleDataBounds(visibleBegin, visibleEnd);
// loop over and draw segments of unselected/selected data:
QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
getDataSegments(selectedSegments, unselectedSegments);
allSegments << unselectedSegments << selectedSegments;
for (int i = 0; i < allSegments.size(); ++i)
{
bool isSelectedSegment = i >= unselectedSegments.size();
QCPBarsDataContainer::const_iterator begin = visibleBegin;
QCPBarsDataContainer::const_iterator end = visibleEnd;
mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i));
if (begin == end)
continue;
for (QCPBarsDataContainer::const_iterator it = begin; it != end; ++it)
{
// draw bar:
if (isSelectedSegment && mSelectionDecorator)
{
mSelectionDecorator->applyBrush(painter);
mSelectionDecorator->applyPen(painter);
}
else
{
painter->setBrush(mBrush);
painter->setPen(mPen);
}
applyDefaultAntialiasingHint(painter);
QRectF barRect = getBarRect(it->key, it->value); //自己加的 绘制矩形
float ww = barRect.width();
//这两个设置可以修改柱状图与Y轴的距离
// barRect.setLeft(barRect.left()+ww-20); //设置矩形的左边缘
// barRect.setRight(barRect.right()+ww-20);//设置矩形的右边缘
barRect.setLeft(barRect.left()+ww);
barRect.setRight(barRect.right()+ww);
//绘制多边形
painter->drawPolygon(barRect);
// 以上是拷贝的源码部分
painter->drawPolygon(barRect);
// 我们仅需在 painter->drawPolygon(barRect); 这行下增加以下的内容即可
// 计算文字的位置
// mFont.setPointSize(6);
painter->setFont(mFont); // 设置字体
QString text = QString::number(it->value, 'g', 2); // 取得当前value轴的值,保留两位精度
QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip | mTextAlignment, text); // 计算文字所占用的大小
if (mKeyAxis.data()->orientation() == Qt::Horizontal) { // 当key轴为水平轴的时候
if (mKeyAxis.data()->axisType() == QCPAxis::atTop) // 上轴,移动文字到柱状图下面
textRect.moveTopLeft(barRect.bottomLeft() + QPointF(0, mSpacing));
else // 下轴,移动文字到柱状图上面
textRect.moveBottomLeft(barRect.topLeft() - QPointF(0, mSpacing));
textRect.setWidth(barRect.width());
painter->drawText(textRect, Qt::TextDontClip | mTextAlignment, text);
}
else { // 当key轴为竖直轴的时候
if (mKeyAxis.data()->axisType() == QCPAxis::atLeft) // 左轴,移动文字到柱状图右边
textRect.moveTopLeft(barRect.topRight() + QPointF(mSpacing, 0));
else // 右轴,移动文字到柱状图左边
textRect.moveTopRight(barRect.topLeft() - QPointF(mSpacing, 0));
textRect.setHeight(barRect.height());
painter->drawText(textRect, Qt::TextDontClip | mTextAlignment, text);
}
}
}
}
3、.h文件
custombars.h
#ifndef CUSTOMBARS_H
#define CUSTOMBARS_H
#include "qcustomplot.h"
class CustomBars : public QCPBars
{
Q_OBJECT
public:
explicit CustomBars(QCPAxis *keyAxis, QCPAxis *valueAxis);
Qt::Alignment textAligment() const { return mTextAlignment; }
double spacing() const { return mSpacing; }
QFont font() const { return mFont; }
void setTextAlignment(Qt::Alignment alignment);
void setSpacing(double spacing);
void setFont(const QFont &font);
protected:
Qt::Alignment mTextAlignment; // 文字对齐方式
double mSpacing; // 文字与柱状图的间距,这里按像素大小
QFont mFont; // 文字使用的字体
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
};
#endif // CUSTOMBARS_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "custombars.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
CustomBars *minBar, *maxBar, *fossil;
public:
void initBar();
void addValue();
};
#endif // WIDGET_H