Qt总结(六)-- 图表数据曲线

不要浮躁,多总结

QCustomplot

源代码下载
◆ 运行两个example,优秀

.pro文件添加QT += printsupport

解读axis-tags

坐标轴

QCustomplot 类中的坐标轴成员有QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
其中*xAxis表示横坐标轴,*xAxis2表示横坐标轴,*yAxis纵坐标轴,*yAxis2纵坐标轴
但可以有每个区域可以添加多个坐标轴,如使用mPlot->axisRect()->addAxis(QCPAxis::atLeft);添加一个左标轴。
使用mPlot->axisRect()->axis(QCPAxis::atLeft, index)来访问,index是编号。
xAxis、xAxis2、yAxis、yAxis2这四个默认指向index为0的坐标轴。
在这里插入图片描述

◆setRange()有两种重载形式,如直接setRange(1,3) ,就是设置1~3
另一种重载形式如下,setRange(1,3,Qt::AlignRight) 是设置-2~1

void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment)
{
  if (alignment == Qt::AlignLeft)
    setRange(position, position+size);
  else if (alignment == Qt::AlignRight)
    setRange(position-size, position);
  else // alignment == Qt::AlignCenter
    setRange(position-size/2.0, position+size/2.0);
}

曲线图 QPointer<QCPGraph>

创建并设置对应的横纵坐标轴

QPointer<QCPGraph> mGraph;
mGraph = mPlot->addGraph(mPlot->xAxis, mPlot->axisRect()->axis(QCPAxis::atRight, 0));
mGraph->setPen(QPen(QColor(250, 120, 0))); 

使用AxisTag可以在坐标轴上实时显示当前值

mTag = new AxisTag(mGraph->valueAxis());  //创建并指定坐标轴
mTag->setPen(mGraph->pen());

添加数据使用addData,两种重载形式

void QCPGraph::addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
void QCPGraph::addData(double key, double value)

◆ onlyEnlarger true只放大不缩小 inKeyRange true则根据当前显示的数值缩放,有一种实时跟踪的效果

  mGraph->rescaleValueAxis(bool onlyEnlarger , bool inKeyRange ); //ValueAxis纵坐标轴  KeyAxis横坐标轴 

◆设置完graph的数值后

mPlot->replot();  //更新

解读scrollbar-axis-range-control
使用枚举enum Interaction可以设置各种选项,实现缩放

  //QCP::iRangeDrag        可以拖动坐标轴  QCP::iRangeZoom   鼠标滚轮放大缩小
  //QCP::iSelectPlottables 选中曲线加粗   QCP::iMultiSelect 可以多选
  //QCP::iSelectAxes       坐标轴可选     QCP::iSelectLegend 图例可选
  ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);  //交互

连接坐标轴和滑动条,同步改变

  // create connection between axes and scroll bars: 
  connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(horzScrollBarChanged(int)));
  connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(vertScrollBarChanged(int)));
  connect(ui->plot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(xAxisChanged(QCPRange)));
  connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(yAxisChanged(QCPRange)));

MyQCP

结合axis-tags和scrollbar-axis-range-control两者功能

功能

(1)动态显示数据曲线 (axis-tags)
(2)双击控件弹出一个大窗口,显示历史500帧的数据,可以拖动放大,缩小 (scrollbar-axis-range-control)

connect(mPlot,SIGNAL(mouseDoubleClick(QMouseEvent*)),this,SLOT(mouseDoubleClickSlot(QMouseEvent*)));

使用

(1)工程加入axistag.cpp、qcustomplot.cpp、myqcp.cpp及对应的头文件,由于添加时是添加整个文件夹(便于管理),所以包含头文件时得指明其绝对路径。。pro 文件增加Qt +=printsupport
(2) MyQCP* plot

plot = new MyQCP(this);  //this 父控件
plot->setSize(330,180);  
plot->setGeometry(420,70,330,180);

(3)增加数据时调用addGraphData(),其中key 横坐标使用 plot->mGraph->dataCount(),

void MyQCP::addGraphData(double key, double value)

补充:

(1)点击选择曲线上的点
 // connect slot that shows a message in the status bar when a graph is clicked:
 connect(plot, SIGNAL(plottableClick(QCPAbstractPlottable*,int,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*,int)));

槽函数void graphClicked(QCPAbstractPlottable *plottable, int dataIndex)里获取选取的点的值

double dataValue = plottable->interface1D()->dataMainValue(dataIndex);

新建一个graph,设置点型和大小,然后只绘制被选中的点

 //graph2 用于点被选中时加粗显示
plot->addGraph();
plot->graph(2)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDiamond));
QPen graphPen;
graphPen.setColor(QColor(100,0, 255));
graphPen.setWidthF(5);
plot->graph(2)->setPen(graphPen);

完整的槽函数如下

void ScrollBox::graphClicked(QCPAbstractPlottable *plottable, int dataIndex)
{
    //点击曲线拐点附近的非曲线区域有时也会触发点击事件,dataIndex为0
     // since we know we only have QCPGraphs in the plot, we can immediately access interface1D()
     // usually it's better to first check whether interface1D() returns non-zero, and only then use it.
        double dataValue = plottable->interface1D()->dataMainValue(dataIndex);
        QVector<double> d0,d1;
        plot->graph(2)->setData(d0,d1);  //空的数据,清空graph
        plot->graph(2)->addData((qreal)dataIndex, dataValue);

        plot->replot();
}

(2)右键菜单选择要显示的曲线
  1. 给控件设置上下文菜单策略 setContextMenuPolicy(Qt::CustomContextMenu)
  2. 设置该策略后当我们右键点击控件时qt会发送一个信号 void QWidget::customContextMenuRequested(const QPoint &pos) ,其中参数pos用来传递右键点击时的鼠标的坐标,这个坐标一般是相对于控件左上角而言的;
  3. 设置相应的槽函数,在槽函数中显示菜单,菜单设置好QAction控制曲线的显示或隐藏

[具体步骤]
(1)头文件添加

#include<QAction>
#include<QMenu>

    //右键菜单
    QAction * graph0_Action;
    QAction * graph1_Action;
    QMenu * graphMenu;
    enum graphPlot {
      showGraph0=0x001,
      showGraph1=0x010,
      showGraph2=0x100,
      hideGraph0=0x110,
      hideGraph1=0x101,
      hideGraph2=0x011,
    };

(2)cpp中

mPlot->setContextMenuPolicy(Qt::CustomContextMenu);
connect(mPlot,&QWidget::customContextMenuRequested,[=](const QPoint &pos)
{
    qDebug()<<pos;//参数pos用来传递右键点击时的鼠标的坐标,这个坐标一般是相对于控件左上角而言的
    graphMenu->exec(QCursor::pos());
});

graphMenu初始化

//右键菜单选择显示曲线
graph0_Action = new QAction(QString::fromLocal8Bit("原始数据"),this);
graph1_Action = new QAction(QString::fromLocal8Bit("卡尔曼滤波"),this);
graph0_Action->setCheckable(true);  //可勾选
graph1_Action->setCheckable(true);

graphPlotFlag = 0;
graphPlotFlag|=graphPlot::showGraph1;  //默认显示
graph1_Action->setChecked(true);
checkState0 =false; checkState1 = true;

graphMenu = new QMenu(this);
//动作添加到菜单
graphMenu->addAction(graph0_Action);
graphMenu->addAction(graph1_Action);

//给动作设置信号槽
connect(graph0_Action, &QAction::triggered, [=]()
{
    if(!checkState0)
    {
        graphPlotFlag|=graphPlot::showGraph0;
        graph0_Action->setChecked(true);
        checkState0 = true;
    }
    else
    {
        graphPlotFlag&=graphPlot::hideGraph0;
        graph0_Action->setChecked(false);
        checkState0 = false;
    }

});
//给动作设置信号槽
connect(graph1_Action, &QAction::triggered, [=]()
{
    if(!checkState1)
    {
        graphPlotFlag|=graphPlot::showGraph1;
        graph1_Action->setChecked(true);
        checkState1 = true;
    }
    else
    {
        graphPlotFlag&=graphPlot::hideGraph1;
        graph1_Action->setChecked(false);
        checkState1 = false;
    }
});

在这里插入图片描述

各版本下载列表,5.8以后没有单独的msvc版本,安装时可以勾选

Qt Charts 在Qt4就有了,不过需要商业许可。qt5.7.0开始直接开放了,安装时默认会勾选,如左图所示。在工程的.pro文件中加入QT += charts 就可以使用了

设置曲线样式

//点与点直接的连接类型 lsNone 无连接,散点图  lsLine 直线连接 
mPlot->graph(1)->setLineStyle(QCPGraph::lsNone);
mPlot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDiamond));//点型
QPen graphPen;
graphPen.setColor(QColor(100,0, 255));//颜色
graphPen.setWidthF(5);//粗细
mPlot->graph(1)->setPen(graphPen);

简单显示一条曲线

(1)头文件加入

#include <QValueAxis>
#include<QChartView>
#include<QLineSeries>
#include<QPieSeries>
using namespace QtCharts;

(2)
在ui设计界面使用Qt Creator添加一个widget组件,然后提升为QChartView。提升的时候,这样写提升为的类:QtCharts::QChartView,头文件写:qchartview.h
(3)
注意:需先addSeries(),再设置坐标轴,否则显示出的线不会根据坐标轴自适应大小

QChart* c = new QChart();
//将数据添加到QLineSeries中
QLineSeries* line1 = new QLineSeries();
for(int x=0;x<ROI.grayShow.size();x++)
{
    line1->append(x,ROI.grayShow[x].y);
}
c->addSeries(line1);  //先添加数据
c->legend()->hide();  //隐藏图例

c->createDefaultAxes();  // 建立坐标轴
c->axisX()->setRange(0,640); //设置范围
c->axisX()->setGridLineVisible(true);  //网格线可见
c->axisY()->setRange(0,255);
c->axisY()->setGridLineVisible(true);  //网格线可见

c->setTitle(QStringLiteral("中线灰度分布"));  //QStringLiteral 解决中文显示乱码

ui->defectWaveform->setChart(c);

Qt使用QChart制作多路虚拟示波器

https://blog.csdn.net/qq_37700564/article/details/85271907

动态实时显示多条折线图

https://blog.csdn.net/qq_41399894/article/details/87805015

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值