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 关键代码

        头文件里面的部分函数:

public:
    int m_WaveIndex;
    QCPMarginGroup *marginGroup;
    QString currentFileName;
    int model;
    QVector<QCPAxisRect *>axisList;
    SetYValueDialog mSetYValueDialog;
    RecFile *pRecGlobal;
    bool bCursorMoveShow;
    QVector<QCPItemText *> vectorQCPItemText;
    QCPAxisRect * rect;
    void SetModelState(Model _model);
    void UpdataAll();
    void ModelSingleCoord();
    void ModelXMulY_Coord();
    void ModelMulCoord();
    void ModelChange(int _model = 0);
    void RemoveQCPAxisRectAll();
    void SetVisbleQCPAxisRect();
    void CreateQCPAxisRect();
    void connectAllxAsix(bool on);
    void CreateQCPAxisRect(int axis_num);
    void UpdataViewTable();
    void ClearViewTable();
    void ReloadCustomPlot();
    void loadFileTXTFile(QString fileName);
    void ClearQCPItemText();
    void dragEnterEvent(QDragEnterEvent *event) override;   //拖入事件

    void dropEvent(QDropEvent *event) override;             //拖入松开事件
};
        1 实现多坐标系的加入删除,动态更新
void MainWindow::RemoveQCPAxisRectAll()
{
    ui->customplot->clearGraphs();
    for(int i = 0;i < axisList.count();i++)
    {
        ui->customplot->plotLayout()->remove(axisList.at(i));
        QCPAxisRect * rect = axisList.at(i);
        rect = nullptr;
    }
    axisList.clear();
    //此处个人理解删除元素后重新布局
    //不执行元素数量不会改变
    ui->customplot->plotLayout()->simplify();
    qDebug()<<ui->customplot->plotLayout()->elementCount();


}

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

void MainWindow::CreateQCPAxisRect(int axis_num)
{

    ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0));
    ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft , marginGroup);
    for(int i = 0;i < axis_num;i++){

        QCPAxisRect *rect = new QCPAxisRect(ui->customplot);

        rect->setMarginGroup(QCP::msLeft , marginGroup);
        rect->setAutoMargins(QCP::MarginSide::msLeft | QCP::MarginSide::msRight);
        
        rect->axis(QCPAxis::atBottom)->setRange(0,2000);
        rect->setRangeDrag(Qt::Horizontal | Qt::Vertical); //水平方向拖动

        rect->setRangeZoom(Qt::Horizontal | Qt::Vertical); //水平方向缩放
        if(i == axis_num - 1)
        {
            rect->setMargins(QMargins(0, 0, 0, 20));
        }

        if(!ui->customplot->plotLayout()->hasElement(i+1,0))
            ui->customplot->plotLayout()->addElement(i+1,0,rect);

        axisList.append(rect);

    }
    connectAllxAsix(true);
    ui->customplot->plotLayout()->simplify();

}

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

ui->customplot->plotLayout()->addElement(i+1,0,rect);
         2 坐标系X轴同步
void MainWindow::connectAllxAsix(bool on)
{

    for (int i = 0; i < axisList.count(); ++i) {
        if(on){
            connect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
            connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
        }
        else
        {
            disconnect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
            disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
        }

        for (int j = i+1; j < axisList.count(); ++j) {
            if(on)
            {

                connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
                connect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
            }
            else
            {
                disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
                disconnect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
            }

        }
    }
}

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

        3 多坐标系中显示游标
void MainWindow::mouseMoveEvent( QMouseEvent *event ) {
    //return ;
    if ( !ui->customplot->viewport().contains( event->pos() ) )
        return;
    if ( RubBand->isVisible() ) {
        QPoint EndPoint = event->pos();
        EndPoint.setY(EndPoint.y() + 58);

//        EndPoint.setY( ui->customplot->height() );
        RubBand->setGeometry( QRect( StartPoint, EndPoint ).normalized() );
    }

    if(!bCursorMoveShow)
        return ;
    //获取鼠标坐标,相对父窗体坐标
    int x_pos = event->pos().x();
    int y_pos = event->pos().y();
    double x_val = 0;//ui->customplot->xAxis->pixelToCoord( x_pos );
    double y_val = 0;//ui->customplot->yAxis->pixelToCoord( y_pos );
    //鼠标坐标转化为CustomPlot内部坐标
    for(int i = 0;i < ui->customplot->axisRectCount(); i++)
    {
        if(event->pos().x() > ui->customplot->axisRects().at(i)->left() && event->pos().y() < ui->customplot->axisRects().at(i)->bottom()\
                &&event->pos().x() <ui->customplot->axisRects().at(i)->right() && event->pos().y() > ui->customplot->axisRects().at(i)->top())
        {
            //不要这样转换
//            x_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atBottom)->pixelToCoord(x_pos);
//            y_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atLeft)->pixelToCoord(y_pos);
            tracer->setClipAxisRect(ui->customplot->axisRects().at(i));
            tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i));

        }
    }
    x_val = ui->customplot->xAxis->pixelToCoord(x_pos);
    y_val = ui->customplot->yAxis->pixelToCoord(y_pos);
    qDebug()<<"x_val:"<<x_val<<",y_val:"<<y_val;
    QList<QCPGraph*> listQCPGraph = ui->customplot->selectedGraphs();
    if(listQCPGraph.isEmpty())
    {
        tracer->setVisible(false);
        //bSelectGraph = false;
        tracerLabel->setVisible(false);
        ui->customplot->replot();
    }
    else
    {
        QCPGraph* curGraph = listQCPGraph.at(0);
        CDatabind* pUserDat = (CDatabind*)curGraph->userData(0);
        double value;
        double num = 0;
        int index = x_val;
        if(pUserDat)
        {
            int m_nWaveInd = pUserDat->m_nWaveInd;
            num = curGraph->data()->at(index)->key;
            value = curGraph->data()->at(index)->value;
            for(int j = mMoveTime[m_nWaveInd].count() -1; j >= 0;j--)
            {
                sMoveTime var;
                var = mMoveTime[m_nWaveInd].at(j);
                if(var.name == "Y*")
                {
                    if(var.num != 0)
                    {
                        value = value / var.num;
                       
                    }

                }
                else
                {
                    value = value - var.num;
                }
            }

        }
        QString mGraphInfo;

        mGraphInfo = m_pViewTable->currentItem()->text();

        tracer->setVisible(true);
        tracerLabel->setVisible(true);

        tracer->position->setCoords(x_val, y_val);

        tracerLabel->setText( mGraphInfo+"\n( X:"+QString::number(num) +
                             ",Y:"+QString::number(value) + " )" );
        pCurLabel[0]->setText("CurX:"+QString::number(num));
        pCurLabel[1]->setText("CurY:"+QString::number(value));
        ui->customplot->replot();
    }
}

重写了mouseMoveEvent函数,其中

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

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

 4 添加曲线函数
void MainWindow::InsertGraph(RecFile *pRec,int nWaveInd){
    QCPGraph *graph;
    Qt::CheckState bSet;
    bSet = m_pViewTable->item(nWaveInd,0)->checkState();

    if(!bSet && model == sMulCoord )
        graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\
                                         ui->customplot->axisRect()->axis(QCPAxis::atLeft));
    else if(model == sMulCoord && axisList.at(m_WaveIndex) != nullptr){
        graph = ui->customplot->addGraph(axisList.at(m_WaveIndex)->axis(QCPAxis::atBottom),axisList.at(m_WaveIndex )->axis(QCPAxis::atLeft));
        m_WaveIndex++;
    }
    else
        graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\
                                         ui->customplot->axisRect()->axis(QCPAxis::atLeft));

    graph->setVisible(bSet);
    graph->setData(pRec->Key,pRec->DatWave[nWaveInd]);

    graph->setPen(QPen(QColor::fromHsl((nWaveInd * 30) % 256,255 - (nWaveInd * 30) / 16,128)));
    graph->setName(m_pViewTable->item(nWaveInd,0)->text());
    CDatabind *m_pUserData = new CDatabind();
    m_pUserData->SetUserData(pRec->nFileInd,nWaveInd);
    graph->setUserData(0,m_pUserData);
    graph->setAdaptiveSampling(true);
}

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

5 创建单X轴多Y轴坐标系
void MainWindow::ModelXMulY_Coord()
{
    ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0));
    ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft , marginGroup);
    for(int i = 0;i < m_pViewTable->rowCount();i++){
        QCPAxis *newAxis = new QCPAxis(ui->customplot->axisRect(),QCPAxis::atLeft);
        newAxis->setBasePen(QPen(m_pViewTable->item(i,1)->backgroundColor()));
        newAxis->setTickLabelColor(m_pViewTable->item(i,1)->backgroundColor());
        //添加多个Y轴
        ui->customplot->axisRect()->addAxis(QCPAxis::atLeft,newAxis);
        axisList_Y.append(newAxis);

    }
    //根据CheckBox是否可见
    for(int i = 0;i < m_pViewTable->rowCount() ;i++){
        if(!m_pViewTable->item(i,0)->checkState())
            ui->customplot->axisRect()->axis(QCPAxis::atLeft,i + 1)->setVisible(false);
    }
    //是否显示Y轴坐标
    if(!bShowYCoord){
        for(int i = 0;i < m_pViewTable->rowCount() ;i++){

            ui->customplot->axisRect()->axis(QCPAxis::atLeft,i + 1)->setVisible(false);
        }

    }
    qDebug()<<"ModelXMulY_Coord"<<ui->customplot->axisRect()->axes().count();
    qDebug()<<"ModelXMulY_Coord QCPAxis::atLeft"<<ui->customplot->axisRect()->axes(QCPAxis::atLeft).count();
    ui->customplot->plotLayout()->simplify();

    horizontal.clear();
    horizontal.append(ui->customplot->axisRect()->axis(QCPAxis::atBottom));
    //设置Y轴坐标系的缩放
    ui->customplot->axisRect()->setRangeZoomAxes(horizontal,axisList_Y);

}

  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
QCustomPlot中,可以通过添加多个坐标系来实现绘制多个图表的需求。 一个坐标系可以理解为一个用于绘制图表的独立空间,通过将图表绘制在不同的坐标系上,可以同时显示多个图表,并且可以独立设置不同的坐标轴、网格、数据等属性。 要创建多个坐标系,首先需要创建QCustomPlot对象,然后通过调用其addGraph()函数来添加图表,并设置所需的属性。接下来,通过调用addAxis()函数来添加坐标轴,并设置坐标轴的显示位置、范围、刻度等属性。每个图表都可以拥有一个独立的X轴和Y轴,也可以复用已经创建的坐标轴。 在绘制多个图表时,可以通过QCPAxisRect来控制每个坐标系的位置和大小。可以使用setAxisRect()函数将图表指定到所需的坐标系中,并设置相应的位置和大小。 最后,使用replot()函数来重新绘制图表,并显示在界面上。 举个例子,可以通过以下步骤实现在一个QCustomPlot对象中绘制多个坐标系的功能: 1. 创建QCustomPlot对象:QCustomPlot *customPlot = new QCustomPlot(this); 2. 添加图表并设置属性: QCPGraph *graph1 = customPlot->addGraph(); // 设置图表1的属性 QCPGraph *graph2 = customPlot->addGraph(); // 设置图表2的属性 3. 添加坐标轴并设置属性: QCPAxis *xAxis1 = customPlot->xAxis; // 设置x轴的属性 QCPAxis *yAxis1 = customPlot->yAxis; // 设置y轴的属性 QCPAxis *xAxis2 = customPlot->axisRect()->addAxis(QCPAxis::atBottom); // 设置图表2的x轴属性 QCPAxis *yAxis2 = customPlot->axisRect()->addAxis(QCPAxis::atLeft); // 设置图表2的y轴属性 4. 设置图表位置和大小: customPlot->plotLayout()->addElement(0, 0, customPlot->axisRect()); // 设置图表1的位置和大小 customPlot->plotLayout()->addElement(0, 1, customPlot->axisRect()); // 设置图表2的位置和大小 5. 调整坐标系的范围和刻度等属性,通过调用replot()函数重新绘制图表。 通过以上步骤,我们可以在一个QCustomPlot对象中创建多个坐标系,并绘制不同的图表,实现多个图表的显示
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值