[AssistantTool]_11_添加asc解析并显示波形

Posted 暮色1994

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[AssistantTool]_11_添加asc解析并显示波形相关的知识,希望对你有一定的参考价值。

[AssistantTool]_11_添加asc解析并显示波形

创建时间:20210809 09:16:54

介绍

  • 参照QtStudy工程Tool中11_AscAnalyse程序,将Asc文件解析和波形显示功能集成到此工具中。

集成样式

主要代码如下

  • qcustomplot使用

    void AscAnalyseForm::setupPlot(int lineNum, QVector<double> times, QVector<double> values)
    {
    // The following plot setup is mostly taken from the plot demos:
    ui->plot->addGraph();
    ui->plot->graph()->setLineStyle(QCPGraph::lsStepLeft); // 线的类型
    ui->plot->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));    // 每个数据绘制一个示意点
    ui->plot->graph()->setPen(QPen(QColor(qrand()%100+100, qrand()%100+100, qrand()%100+100, 255))); // 线的颜色
    ui->plot->graph(lineNum)->setData(times, values);
    ui->plot->axisRect()->setupFullAxesBox(false);
    ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    
    }
    
    
    void AscAnalyseForm::pushButton_UpdateFile_OnCliecked()
    {
        datalist.clear();
        datalist = DataUtil::readAscFile(ui->lineEdit->text());
        qDebug() << "file:" << ui->lineEdit->text() << "datalist.count():" << datalist.count();
    }
    
    void AscAnalyseForm::pushButton_UpdateSignal_OnCliecked()
    {
        QVector<double> times;
        QVector<double> values;
        int count;
        double valMin = 1000000;
        double valMax = -1000000;
    
        double timMin = 1000000;
        double timMax = -1000000;
    
        if( datalist.count() <= 0 )
        {
            pushButton_UpdateFile_OnCliecked();
            if( datalist.count() <= 0 )
            {
                ui->statusBar->setText("File Data Size is Zero, Reread File");
                return;
            }
        }
    
        int dataOffset = ui->lineEdit_signalDataOffset->text().toInt();
        for ( int i = 0; i < model->rowCount(); i++)
        {
    
            int signalID = model->item(i,0)->text().toInt(nullptr, 16);
            int signalOffset = model->item(i,1)->text().toInt();
            int signalLen = model->item(i,2)->text().toInt();
            QString txrx = model->item(i,3)->text();
            count = DataUtil::readAscSignal(datalist, dataOffset, signalID, signalOffset, signalLen, &times, &values, txrx.contains("Tx"), txrx.contains("Rx"));
            if( count > 0 )
            {
                setupPlot(i, times, values);
    
                foreach (double val, times)
                {
                    if( timMin > val )
                    {
                        timMin = val;
                    }
                    if( timMax < val )
                    {
                        timMax = val;
                    }
                }
    
                foreach (double val, values)
                {
                    if( valMin > val )
                    {
                        valMin = val;
                    }
                    if( valMax < val )
                    {
                        valMax = val;
                    }
                }
                qDebug() << "timMin=" << timMin << " timMax:" << timMax;
                qDebug() << "valMin=" << valMin << " valMax:" << valMax;
                ui->plot->xAxis->setRange(timMin-1, timMax+1);
                ui->plot->yAxis->setRange(valMin-1, valMax+1);
                ui->plot->replot();
            }
            else
            {
                ui->statusBar->setText("num:" + QString::number(i) + " data size is empty : " + QString::number(signalID, 16));
            }
        }
    }
    
    void AscAnalyseForm::wheelEvent(QWheelEvent *event)
    {
        static int i=0;
        i++;
    
        if (ui->plot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))
        {
            ui->plot->axisRect()->setRangeZoom(ui->plot->xAxis->orientation());
        }
        else if (ui->plot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))
        {
            ui->plot->axisRect()->setRangeZoom(ui->plot->yAxis->orientation());
        }
        else
        {
            ui->plot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);
        }
    }
    
  • 读取文件和解析数据

    
    /**
    * @brief readAscFile
    * 将文件内容读取到字符串列表中
    * @param fileName:文件名及路径
    * @return:包含文件内容的字符串列表
    */
    QStringList DataUtil::readAscFile(QString fileName)
    {
        QFile ascFile(fileName);
        QStringList dataList;
        dataList.clear();
        if (ascFile.open(QIODevice::ReadWrite)) //对asc文件进行读写操作
        {
            QTextStream stream(&ascFile);
            while (!stream.atEnd())
            {
                dataList.push_back(stream.readLine()); //保存到List当中
            }
                ascFile.close();
        }
        else
        {
            QMessageBox::about(NULL, "asc文件", "未打开该文件!");
        }
        return dataList;
    }
    
    
    /**
    * @brief DataUtil::readAscSignal
    * @param strList:所有asc数据
    * @param signalIndex:有效数据的偏移位置
    * @param signalID:信号ID
    * @param signalOffset:信号值的偏移量
    * @param signalLen:信号值占用位数
    * @param time:时间轴
    * @param val:数据轴
    * @param Tx:是否检测Tx方向, True检测,False不检测
    * @param Rx:是否检测Tx方向, True检测,False不检测
    * @return:过滤出来的数据个数
    */
    int DataUtil::readAscSignal(QStringList strList, int signalIndex, int signalID, int signalOffset, int signalLen, QVector<double> *time, QVector<double> *val, bool Tx, bool Rx)
    {
        int value = -1;
        if( time == nullptr || val == nullptr || strList.count() <= 0)
        {
            return 0;
        }
        time->clear();
        val->clear();
    
    
        foreach (QString line, strList)
        {
            line = line.simplified();
            if( line.contains("version") )
            {
                qDebug() << line.split(QRegExp(" version ")).at(1);
            }
            else if( (Tx && line.contains(" Tx ")) || (Rx && line.contains(" Rx ")) )
            {
                // 只有Tx为True才会进行后面contains Tx判断,  Rx为True才会进行contains Rx判断
                QStringList list = line.split(" ");
                if( list.at(4).toInt(nullptr, 16) == signalID )
                {
                    qDebug() << list;
                    time->append(list.at(0).toDouble());
                    value = getArrayOffsetValue(list, signalIndex, signalOffset, signalLen);
                    val->append(value);
                }
            }
    
        }
    
        return time->count();
    }
    
    /**
    * @brief DataUtil::getArrayOffsetValue
    * 从字符串列表中获取对应的数据
    * @param strList:字符串列表
    * @param signalIndex:真实有效数据偏移位置
    * @param offset:提取数 = 据在有效数据 中的偏移位置
    * @param len:待提取的位数
    * @return :提取出来的数值, >0:正常-1:异常
    */
    int DataUtil::getArrayOffsetValue(QStringList strList, int signalIndex, int offset, int len)
    {
        int value = 0; // 计算出来的值
        int valueOffset = 0; // 记录已经偏移了多少个字节了
        int lenLeft = len; // 还需要提取多少位
        int arrayIndex = 0; // 当前需要处理字节在 array中的位置
        int arrayBitIndex = 0;  // 当前需要处理位bit在 array中的位置
    
        unsigned int byteVal = 0;
    
        qDebug() << "list.size:" << strList.count() << " signalIndex:" << signalIndex << " offset:" << offset << " len:"<< len;
        while(lenLeft) // 提取需要的位,直到提取完成
        {
            arrayIndex = offset/8; // 当前需要处理字节在array中的位置
            arrayBitIndex = offset%8;  // 当前需要处理位在 array中的位置, 且此Byte可以处理的位数// 当前需要处理位bit在 array中的位置
    
    
            qDebug() << "lenLeft:" << lenLeft << " arrayIndex:" << arrayIndex << " 8-arrayBitIndex:" << 8-arrayBitIndex << \\
                        " offset:" << offset << " arrayBitIndex:" << arrayBitIndex << " value:" << value;
    
            if( strList.count() < arrayIndex+signalIndex )
            {
                return -1;
            }
            byteVal = strList.at(arrayIndex+signalIndex).toInt(nullptr,16);
    
            if( (8-arrayBitIndex) >= lenLeft )
            {
                // 当前字节的bit位数 满足需要提取的位数
    
                for( int j = 0; j < lenLeft; j++ )
                {
                    // 按照对应位为0/1进行处理
                    if( byteVal & (1<<(j+arrayBitIndex)) )
                    {
                        value += (1<<valueOffset);
                        valueOffset++;
                    }
                    else
                    {
                        value += 0;
                        valueOffset++;
                    }
    
                    lenLeft--;
                    offset++;
                }
            }
            else if( ((8-arrayBitIndex) <= lenLeft) && (arrayBitIndex != 0) )
            {
                // 当前字节的bit位数 不够满足需要提取的位数
                for( int j = 0; j < (8-arrayBitIndex); j++ )
                {
                    // 按照对应位为0/1进行处理
                    if( byteVal & (1<<(j+arrayBitIndex)) )
                    {
                        value += (1<<valueOffset);
                        valueOffset++;
                    }
                    else
                    {
                        value += 0;
                        valueOffset++;
                    }
    
                    lenLeft--;
                    offset++;
                }
            }
            else
            {
                value += (byteVal<<valueOffset);
                valueOffset += 8;
                lenLeft -= 8;
                offset += 8;
            }
        }
    
        return value;
    }
    
    
  • 显示图例

    // 显示图例
    ui->plot->legend->setVisible(true);
    ui->plot->legend->setFont(QFont("Helvetica",9));
    ui->plot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignLeft|Qt::AlignTop);
        // 说明:
        //      0 --- 表示 legend 图层索引
        //      1 --- 表示 legend 位置,可选择如下情况;
        //      Qt::AlignLeft|Qt::AlignTop); //图例置于左上
        //      Qt::AlignCenter|Qt::AlignTop);//图例置于中上
        //      Qt::AlignRight|Qt::AlignTop);//图例置于右上
        //      Qt::AlignLeft|Qt::AlignCenter);//图例置于左中
        //      Qt::AlignCenter);             //图例置于正中 
        //      Qt::AlignRight|Qt::AlignCenter);//图例置于右中
        //      Qt::AlignLeft|Qt::AlignBottom);//图例置于左下
    

以上是关于[AssistantTool]_11_添加asc解析并显示波形的主要内容,如果未能解决你的问题,请参考以下文章

[AssistantTool]_11_添加asc解析并显示波形

[AssistantTool]_3_添加TAB示例

[AssistantTool]_3_添加TAB示例

[AssistantTool]_6_添加生成YUV文件的功能

[AssistantTool]_6_添加生成YUV文件的功能

[AssistantTool]_6_添加生成YUV文件的功能