• QCustomPlot单多坐标系显示


    目录

    1 效果图

    2 功能描述

    3 关键代码

             1 实现多坐标系的加入删除,动态更新

             2 坐标系X轴同步

             3 多坐标系中显示游标

             4 添加曲线函数

             5 创建单X轴多Y轴坐标系


    1 效果图

    2 功能描述

            0 三种模式 (1)单X单Y轴 (2)单X多Y轴 (3) 多X多Y轴

            1 可进行单坐标系多坐标系的切换

            2  点击QTableWidget的checkbox可以控制坐标系的数量并显示相应的曲线

            3 在多坐标系中显示游标

            4 更改曲线的颜色

            5 坐标系X轴同步

            6 曲线的放大缩小、左右移动、上下移动

    3 关键代码

            头文件里面的部分函数:

    1. public:
    2. int m_WaveIndex;
    3. QCPMarginGroup *marginGroup;
    4. QString currentFileName;
    5. int model;
    6. QVectoraxisList;
    7. SetYValueDialog mSetYValueDialog;
    8. RecFile *pRecGlobal;
    9. bool bCursorMoveShow;
    10. QVector vectorQCPItemText;
    11. QCPAxisRect * rect;
    12. void SetModelState(Model _model);
    13. void UpdataAll();
    14. void ModelSingleCoord();
    15. void ModelXMulY_Coord();
    16. void ModelMulCoord();
    17. void ModelChange(int _model = 0);
    18. void RemoveQCPAxisRectAll();
    19. void SetVisbleQCPAxisRect();
    20. void CreateQCPAxisRect();
    21. void connectAllxAsix(bool on);
    22. void CreateQCPAxisRect(int axis_num);
    23. void UpdataViewTable();
    24. void ClearViewTable();
    25. void ReloadCustomPlot();
    26. void loadFileTXTFile(QString fileName);
    27. void ClearQCPItemText();
    28. void dragEnterEvent(QDragEnterEvent *event) override; //拖入事件
    29. void dropEvent(QDropEvent *event) override; //拖入松开事件
    30. };
            1 实现多坐标系的加入删除,动态更新
    1. void MainWindow::RemoveQCPAxisRectAll()
    2. {
    3. ui->customplot->clearGraphs();
    4. for(int i = 0;i < axisList.count();i++)
    5. {
    6. ui->customplot->plotLayout()->remove(axisList.at(i));
    7. QCPAxisRect * rect = axisList.at(i);
    8. rect = nullptr;
    9. }
    10. axisList.clear();
    11. //此处个人理解删除元素后重新布局
    12. //不执行元素数量不会改变
    13. ui->customplot->plotLayout()->simplify();
    14. qDebug()<customplot->plotLayout()->elementCount();
    15. }

    此函数全部删除了QVectoraxisList里面的坐标轴,没有删除QCustomPlot默认的那个,也就是ui->customplot->axisRect()默认索引为0这个没有删除

    1. void MainWindow::CreateQCPAxisRect(int axis_num)
    2. {
    3. ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0));
    4. ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft , marginGroup);
    5. for(int i = 0;i < axis_num;i++){
    6. QCPAxisRect *rect = new QCPAxisRect(ui->customplot);
    7. rect->setMarginGroup(QCP::msLeft , marginGroup);
    8. rect->setAutoMargins(QCP::MarginSide::msLeft | QCP::MarginSide::msRight);
    9. rect->axis(QCPAxis::atBottom)->setRange(0,2000);
    10. rect->setRangeDrag(Qt::Horizontal | Qt::Vertical); //水平方向拖动
    11. rect->setRangeZoom(Qt::Horizontal | Qt::Vertical); //水平方向缩放
    12. if(i == axis_num - 1)
    13. {
    14. rect->setMargins(QMargins(0, 0, 0, 20));
    15. }
    16. if(!ui->customplot->plotLayout()->hasElement(i+1,0))
    17. ui->customplot->plotLayout()->addElement(i+1,0,rect);
    18. axisList.append(rect);
    19. }
    20. connectAllxAsix(true);
    21. ui->customplot->plotLayout()->simplify();
    22. }

    此函数创造多坐标系并加入到边框组marginGroup中,使得Y轴保持一致,由于有默认的坐标系存在,所以这里是i + 1

    ui->customplot->plotLayout()->addElement(i+1,0,rect);
             2 坐标系X轴同步
    1. void MainWindow::connectAllxAsix(bool on)
    2. {
    3. for (int i = 0; i < axisList.count(); ++i) {
    4. if(on){
    5. connect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    6. connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    7. }
    8. else
    9. {
    10. disconnect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    11. disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    12. }
    13. for (int j = i+1; j < axisList.count(); ++j) {
    14. if(on)
    15. {
    16. connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    17. connect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    18. }
    19. else
    20. {
    21. disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    22. disconnect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    23. }
    24. }
    25. }
    26. }

    此函数连接信号和槽实现X轴的同步

            3 多坐标系中显示游标
    1. void MainWindow::mouseMoveEvent( QMouseEvent *event ) {
    2. //return ;
    3. if ( !ui->customplot->viewport().contains( event->pos() ) )
    4. return;
    5. if ( RubBand->isVisible() ) {
    6. QPoint EndPoint = event->pos();
    7. EndPoint.setY(EndPoint.y() + 58);
    8. // EndPoint.setY( ui->customplot->height() );
    9. RubBand->setGeometry( QRect( StartPoint, EndPoint ).normalized() );
    10. }
    11. if(!bCursorMoveShow)
    12. return ;
    13. //获取鼠标坐标,相对父窗体坐标
    14. int x_pos = event->pos().x();
    15. int y_pos = event->pos().y();
    16. double x_val = 0;//ui->customplot->xAxis->pixelToCoord( x_pos );
    17. double y_val = 0;//ui->customplot->yAxis->pixelToCoord( y_pos );
    18. //鼠标坐标转化为CustomPlot内部坐标
    19. for(int i = 0;i < ui->customplot->axisRectCount(); i++)
    20. {
    21. if(event->pos().x() > ui->customplot->axisRects().at(i)->left() && event->pos().y() < ui->customplot->axisRects().at(i)->bottom()\
    22. &&event->pos().x() customplot->axisRects().at(i)->right() && event->pos().y() > ui->customplot->axisRects().at(i)->top())
    23. {
    24. //不要这样转换
    25. // x_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atBottom)->pixelToCoord(x_pos);
    26. // y_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atLeft)->pixelToCoord(y_pos);
    27. tracer->setClipAxisRect(ui->customplot->axisRects().at(i));
    28. tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i));
    29. }
    30. }
    31. x_val = ui->customplot->xAxis->pixelToCoord(x_pos);
    32. y_val = ui->customplot->yAxis->pixelToCoord(y_pos);
    33. qDebug()<<"x_val:"<",y_val:"<
    34. QList listQCPGraph = ui->customplot->selectedGraphs();
    35. if(listQCPGraph.isEmpty())
    36. {
    37. tracer->setVisible(false);
    38. //bSelectGraph = false;
    39. tracerLabel->setVisible(false);
    40. ui->customplot->replot();
    41. }
    42. else
    43. {
    44. QCPGraph* curGraph = listQCPGraph.at(0);
    45. CDatabind* pUserDat = (CDatabind*)curGraph->userData(0);
    46. double value;
    47. double num = 0;
    48. int index = x_val;
    49. if(pUserDat)
    50. {
    51. int m_nWaveInd = pUserDat->m_nWaveInd;
    52. num = curGraph->data()->at(index)->key;
    53. value = curGraph->data()->at(index)->value;
    54. for(int j = mMoveTime[m_nWaveInd].count() -1; j >= 0;j--)
    55. {
    56. sMoveTime var;
    57. var = mMoveTime[m_nWaveInd].at(j);
    58. if(var.name == "Y*")
    59. {
    60. if(var.num != 0)
    61. {
    62. value = value / var.num;
    63. }
    64. }
    65. else
    66. {
    67. value = value - var.num;
    68. }
    69. }
    70. }
    71. QString mGraphInfo;
    72. mGraphInfo = m_pViewTable->currentItem()->text();
    73. tracer->setVisible(true);
    74. tracerLabel->setVisible(true);
    75. tracer->position->setCoords(x_val, y_val);
    76. tracerLabel->setText( mGraphInfo+"\n( X:"+QString::number(num) +
    77. ",Y:"+QString::number(value) + " )" );
    78. pCurLabel[0]->setText("CurX:"+QString::number(num));
    79. pCurLabel[1]->setText("CurY:"+QString::number(value));
    80. ui->customplot->replot();
    81. }
    82. }

    重写了mouseMoveEvent函数,其中

    1. tracer->setClipAxisRect(ui->customplot->axisRects().at(i));
    2. tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i));

    是关键,if(pUserDat)片段中是为了还原曲线放大缩小平移等操作的实际值,可不用理会

     4 添加曲线函数
    1. void MainWindow::InsertGraph(RecFile *pRec,int nWaveInd){
    2. QCPGraph *graph;
    3. Qt::CheckState bSet;
    4. bSet = m_pViewTable->item(nWaveInd,0)->checkState();
    5. if(!bSet && model == sMulCoord )
    6. graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\
    7. ui->customplot->axisRect()->axis(QCPAxis::atLeft));
    8. else if(model == sMulCoord && axisList.at(m_WaveIndex) != nullptr){
    9. graph = ui->customplot->addGraph(axisList.at(m_WaveIndex)->axis(QCPAxis::atBottom),axisList.at(m_WaveIndex )->axis(QCPAxis::atLeft));
    10. m_WaveIndex++;
    11. }
    12. else
    13. graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\
    14. ui->customplot->axisRect()->axis(QCPAxis::atLeft));
    15. graph->setVisible(bSet);
    16. graph->setData(pRec->Key,pRec->DatWave[nWaveInd]);
    17. graph->setPen(QPen(QColor::fromHsl((nWaveInd * 30) % 256,255 - (nWaveInd * 30) / 16,128)));
    18. graph->setName(m_pViewTable->item(nWaveInd,0)->text());
    19. CDatabind *m_pUserData = new CDatabind();
    20. m_pUserData->SetUserData(pRec->nFileInd,nWaveInd);
    21. graph->setUserData(0,m_pUserData);
    22. graph->setAdaptiveSampling(true);
    23. }

    里面很多变量的定义没有写出来,可根据需要灵活变更。

    5 创建单X轴多Y轴坐标系
    1. void MainWindow::ModelXMulY_Coord()
    2. {
    3. ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0));
    4. ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft , marginGroup);
    5. for(int i = 0;i < m_pViewTable->rowCount();i++){
    6. QCPAxis *newAxis = new QCPAxis(ui->customplot->axisRect(),QCPAxis::atLeft);
    7. newAxis->setBasePen(QPen(m_pViewTable->item(i,1)->backgroundColor()));
    8. newAxis->setTickLabelColor(m_pViewTable->item(i,1)->backgroundColor());
    9. //添加多个Y轴
    10. ui->customplot->axisRect()->addAxis(QCPAxis::atLeft,newAxis);
    11. axisList_Y.append(newAxis);
    12. }
    13. //根据CheckBox是否可见
    14. for(int i = 0;i < m_pViewTable->rowCount() ;i++){
    15. if(!m_pViewTable->item(i,0)->checkState())
    16. ui->customplot->axisRect()->axis(QCPAxis::atLeft,i + 1)->setVisible(false);
    17. }
    18. //是否显示Y轴坐标
    19. if(!bShowYCoord){
    20. for(int i = 0;i < m_pViewTable->rowCount() ;i++){
    21. ui->customplot->axisRect()->axis(QCPAxis::atLeft,i + 1)->setVisible(false);
    22. }
    23. }
    24. qDebug()<<"ModelXMulY_Coord"<customplot->axisRect()->axes().count();
    25. qDebug()<<"ModelXMulY_Coord QCPAxis::atLeft"<customplot->axisRect()->axes(QCPAxis::atLeft).count();
    26. ui->customplot->plotLayout()->simplify();
    27. horizontal.clear();
    28. horizontal.append(ui->customplot->axisRect()->axis(QCPAxis::atBottom));
    29. //设置Y轴坐标系的缩放
    30. ui->customplot->axisRect()->setRangeZoomAxes(horizontal,axisList_Y);
    31. }

  • 相关阅读:
    计算机毕业设计springboot+vue+elementUI学生公寓管理系统
    谈谈JS二进制:File、Blob、FileReader、ArrayBuffer、Base64
    Spring的AOP (代理模式)
    CircuitPython入门贴
    学习网络编程No.8【应用层协议之HTTP】
    【C++】解引用 (及指针) 和 引用 的概念区别
    from sklearn import cross_validation 报错的解决方法
    java计算机毕业设计教评系统源码+mysql数据库+系统+lw文档+部署
    2022-11-13
    jq实现多页展示并且进度条轮播
  • 原文地址:https://blog.csdn.net/weixin_44270564/article/details/132858350