curve.h
#ifndef CURVE_H
#define CURVE_H
#include <QObject>
#include "qcustomplot.h"
#include <QTimer>
class Curve : public QObject
{
Q_OBJECT
public:
explicit Curve(QObject *parent = nullptr,QCustomPlot *cplot = nullptr);
~Curve();
QCustomPlot *plot;
QVector<double> //用于生成模拟数据点,可以参考如下
/*QVector<double> x(251), y0(251), y1(251);
for (int i=0; i<251; ++i)
{
x[i] = i;
y0[i] = qExp(-i/150.0)*qCos(i/10.0); // 第一条曲线:y0衰减cos
y1[i] = qExp(-i/150.0); // 第二条曲线:y1衰减指数
} */
QCPItemText *plot_text_tip;
void SetPlotData(double value);
void ClearPlot(void);
private slots:
void PositiveAxisDisplay(void);
void OnPlotClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
private:
void InitPlot(void);
QTimer *dataTimer;
signals:
};
#endif // CTRL_H
curve.cpp
#include "Curve.h"
#include <QDebug>
Curve::Curve(QObject *parent,QCustomPlot *cplot) :
QObject(parent)
{
plot = cplot;
InitPlot();
}
Curve::~Curve()
{
//delete plot;
}
void Curve::SetPlotData(double value)
{
//qDebug() << "SetPlotData" << value;
static int c=0;
double time = QDateTime::currentDateTime().toSecsSinceEpoch();// time elapsed since start of demo, in seconds
if(plot->graph(0)==nullptr)
return;
plot->graph(0)->addData(time,value);
plot->graph(0)->rescaleValueAxis(true);//根据图像最高点最低点自动缩放坐标轴 false:表示范围可以缩小放大,true:只能放大而不会缩小范围。
// 添加扭矩数据
if(plot->graph(1) != nullptr) {
plot->graph(1)->addData(time,value);
// plot->graph(1)->rescaleValueAxis(false); // 自适应Y轴
plot->xAxis->setRange(time, c++, Qt::AlignRight); //设置x轴的范围 显示个数为( )个
plot->replot();//重绘制
}
}
void Curve::PositiveAxisDisplay()
{
if(plot->yAxis->range().lower<0.0){
plot->yAxis->setRangeLower(0);
plot->replot();//重绘制
}
}
void Curve::OnPlotClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
{
Q_UNUSED(plottable);
//qDebug() << event->pos() << plot->size() <<plot->sizePolicy();
//先获取点击的绘图层名称,然后通过名称找到图层ID,再找到对应的数据点 这里因为知道ID 所以直接使用 没有通过名称找
const QCPGraphData *ghd = plot->graph(0)->data()->at(dataIndex);
QDateTime time;
time.setSecsSinceEpoch(ghd->key);
//qDebug() << time.toString("hh:mm:ss");
QString text =time.toString("hh:mm:ss") + " " + QString::number(ghd->value,10,0);
plot_text_tip->setText(text);//文本内容填充
plot_text_tip->setColor(QColor(0,0,0));
plot_text_tip->setPadding(QMargins(2,2,2,2));//文字距离边框几个像素
plot_text_tip->position->setCoords(event->pos().x()+30, event->pos().y()-15);//文本框所在位置
plot_text_tip->setVisible(true);
plot->replot();
}
void Curve::ClearPlot()
{
plot->graph(0)->data().data()->clear();//正确的方式来清除数据
}
//分一个x轴和两个y轴量.
void Curve::InitPlot()
{
QSharedPointer<QCPAxisTickerDateTime> timeTicker(new QCPAxisTickerDateTime);//日期做X轴
timeTicker->setDateTimeFormat("HH:mm:ss");//设置时间格式
plot->xAxis->setTicker(timeTicker);//设置X轴为时间轴
plot->axisRect()->setupFullAxesBox();//四边安上坐标轴
plot->xAxis->ticker()->setTickCount(11);//11个主刻度
plot->xAxis->ticker()->setTickStepStrategy(QCPAxisTicker::tssReadability);//可读性优于设置
plot->xAxis->setLabel("自拟");
plot->yAxis->ticker()->setTickCount(11);//11个主刻度
plot->yAxis->ticker()->setTickStepStrategy(QCPAxisTicker::tssReadability);//可读性优于设置
plot->yAxis->setLabel("自拟");
plot->yAxis2->setLabel("自拟");
plot->yAxis2->ticker()->setTickCount(11);
plot->yAxis2->ticker()->setTickStepStrategy(QCPAxisTicker::tssReadability);
plot->yAxis2->setRange(0, 100); // 例如,设置0到100的范围
plot->yAxis2->setTickLabelFont(QFont("sans", 9)); // 设置刻度字体
plot->yAxis2->setTickLabelColor(Qt::red); // 设置刻度字体颜色
plot->yAxis2->setVisible(true); // 确保右侧Y轴可见
plot->yAxis2->setTickLabels(true);
// 使上下轴、左右轴范围同步
connect(plot->xAxis, SIGNAL(rangeChanged(QCPRange)), plot->xAxis, SLOT(setRange(QCPRange)));
connect(plot->yAxis, SIGNAL(rangeChanged(QCPRange)), plot->yAxis, SLOT(setRange(QCPRange)));
connect(plot->yAxis2, SIGNAL(rangeChanged(QCPRange)), plot->yAxis2, SLOT(setRange(QCPRange))); // 同步右侧Y轴
//正半轴显示
connect(plot,&QCustomPlot::mouseMove,this,&Curve::PositiveAxisDisplay);
connect(plot,&QCustomPlot::mouseWheel,this,&Curve::PositiveAxisDisplay);
/*
iRangeDrag 轴范围是可拖动的 鼠标按住移动坐标
iRangeZoom 轴范围可通过鼠标滚轮缩放 鼠标滚轮缩放曲线
iSelectAxes 轴是可以选择的 轴可以被选中
iSelectLegend 图例可以选择 图例可以被选中
iSelectPlottables 图中的内容可以被选择,(例如:曲线)
*/
plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |
QCP::iSelectLegend | QCP::iSelectPlottables); //设置曲线属性
//第一个图型(粘度)
plot->addGraph();
plot->graph(0)->setPen(QPen(Qt::red));
//plot->graph(0)->rescaleAxes();//让轴范围自己缩放
plot->graph(0)->setLineStyle(QCPGraph::lsLine);//
plot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 2));//显示散点
//第二个图形(扭矩)
plot->addGraph(plot->xAxis,plot->yAxis2);
plot->graph(1)->setPen(QPen(Qt::blue));
plot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc,2));
plot->yAxis2->setRange(0,100);
//显示标签
plot_text_tip = new QCPItemText(plot);
plot_text_tip->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter);
plot_text_tip->position->setType(QCPItemPosition::ptAbsolute);
QFont font;
font.setPixelSize(15);
plot_text_tip->setFont(font); // make font a bit larger
plot_text_tip->setPen(QPen(Qt::black)); // show black border around text
plot_text_tip->setBrush(Qt::white);
plot_text_tip->setVisible(false);
connect(plot, SIGNAL(plottableClick(QCPAbstractPlottable*, int, QMouseEvent*)), this, SLOT(OnPlotClick(QCPAbstractPlottable*, int, QMouseEvent*)));//关联选点信号
//初始化数据
SetPlotData(0.0);
dataTimer = new QTimer(this);
connect(dataTimer,&QTimer::timeout,this,[=](){
static double i=0;
SetPlotData(i++);
});
//dataTimer->start(1000);
}
运行图:
滑动滚轮可做到变化左边y轴和下边x轴大小,因为写死了y是大于0的,所以滑倒负数会重新从0开始绘图。如果不要可以删掉
void Curve::PositiveAxisDisplay()
{
if(plot->yAxis->range().lower<0.0){
plot->yAxis->setRangeLower(0);
plot->replot();//重绘制
}
}
仅供参考学习。