利用QT获取TXT文件中的数据并进行坐标轴的绘制,产生相应波形

 一、获取txt中的数据并保存在缓冲区

//打开并读取相应文件,将所有数据保存在buffer中
    unsigned int buffer[10000];
    QFile file("D:/Qt/work/readtxt/test_8192.txt");//打开txt文件
    if(file.open(QIODevice::ReadOnly))
    {
         int j=0;
         QTextStream in(&file);//QTextStream 可以逐行读取
         while(!in.atEnd())
         {
             QString line=in.readLine();//从文本流中读取一行文本,下一次就读取下一行数据,并将其作为QString返回。
             //QString hexstr("0x");
             //line=line.remove(hexstr);//删除0x
             //SkipEmptyParts--->如果字段为空,则不要将其包含在结果中
             //QStringList items=line.split(",",QString::SkipEmptyParts);
             QStringList items=line.split(" ",QString::SkipEmptyParts);//以空格作为分隔符,且不包含空格
             qDebug()<<"txt文件中第"<<j+1<<"行的数据个数为:"<<items.count()<<endl;//打印每行数据的个数
             bool OK;
             //每items.count()个数据存入一组,将文件中的数据存入buffer中
             for(int i=0;i<items.count();i++)
             {
                 //注意文件中是什么类型的数据,需要合理改变进制!!!!!!!!!!
                 buffer[i+count]=items[i].toUInt(&OK,10);//将QString类型转换为unsigned int类型;以10进制方式读取字符串;OK为判断时是否转换成功
                // qDebug()<<"第"<<i+count<<"个数据为:"<<buffer[i+count];
             }
                qDebug()<<endl;
             j++;
             count+=items.count();
         }
             qDebug()<<"txt文件中数据的总数为:"<<count<<endl;//打印文件中数据的总数
      }
     else
         qDebug()<<"files open error!"<<endl;

二、按照所需要求将buffer中的数据存入drawdata

 //将buffer中符合要求的数据保存在drawdata中
     for(int i=0;i<count/2048;i++)
     {
         flag=2048*i+flag8+flag9;
         if(buffer[flag]==9999999&&buffer[flag+1]==8888888&&buffer[2050+flag]==9999999)
         {
             flag8+=1;//含有8888888的标志位
             for(int j=0;j<2048;j++)
             {
               drawdata[j+2048*valid]=buffer[flag+2+j];
             }
             valid++;//记录有效的2024个数据有多少组
         }
         if(buffer[flag]==9999999)
         {
             flag9+=1;//含有9999999的标志位
         }

     }
     drawdata_count=2048*valid;

三、绘制坐标轴并将获取的数据显示

//绘画事件
void myDialog::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);//相当于QPainter *painter=new QPainter(this);实例化对象写法

    //定义一个(60,40)点-->由w和h去画矩形(大小由窗口大小去控制)
    QRect rect(3*Margin, 2*Margin,width() - 8 * Margin, height() - 4 * Margin);//Margin = 20
    if (!rect.isValid())//矩形有效返回真
        return;

    QPen quiteDark = palette().dark().color().light();
    QPen light = palette().light().color();

    //画竖直方向的垂直线和x轴坐标值
    for (int i = 0; i <= (width() - 8 * Margin)/50; ++i)//0到numXticks
    {
        //间隔为(rect.width() - 1)/ numXticks时为平均间隔
        //此处间隔为50
        int x = rect.left() +50*i;// (i * (rect.width() - 1)/ numXticks);

        painter.setPen(Qt::black);
        painter.drawLine(rect.left(), rect.top(), rect.left(), rect.bottom());
        painter.setPen(Qt::DotLine);//虚线
        painter.drawLine(x, rect.top(), x, rect.bottom());//所有y轴方向线
        painter.setPen(Qt::blue);
        painter.drawLine(x, rect.bottom(), x, rect.bottom() + 5);//x轴的折线和坐标值
        if(i!=0)
        {
        /*flags:   Qt::AlignHCenter | Qt::AlignTop-->靠上垂直居中
        在具有原点(x, y)、宽度和高度的矩形内绘制给定文本。
        void QPainter::drawText(int x, int y, int width, int height,
                                int flags, const QString &text,
                                QRect *boundingRect = Q_NULLPTR)*/
        painter.drawText(x, rect.bottom() + 5, 30, 30,
                         Qt::AlignHCenter | Qt::AlignTop,
                         QString::number(i*50));
       }
    }

    //画水平方向的水平线和y轴坐标值
    int y;
    for (int j = 0; j <= (height() - 4 * Margin)/50; ++j)
    {

        y = rect.bottom() -50*j;// (j * (rect.height() - 1)/ numYticks);
        painter.setPen(Qt::black);
        painter.drawLine(rect.left(), rect.bottom(), rect.right(), rect.bottom());
        painter.setPen(Qt::DotLine);
        painter.drawLine(rect.left(), y, rect.right(), y);//所有x轴方向线
        painter.setPen(Qt::blue);
        painter.drawLine(rect.left() - 5, y, rect.left(), y);//y轴的折线和坐标值
        if(j!=0)
        {
        //AlignRight | Qt::AlignVCenter-->靠右水平居中
        painter.drawText(rect.left() - 2.5*Margin, y - 10, 60, 30,
                         Qt::AlignLeft | Qt::AlignVCenter,
                         QString::number(j*50000));
        }
    }
    painter.drawText(rect.left()-10,rect.top()-10,"ADC值");//Y轴
    painter.drawText(rect.right()+5,rect.bottom()+5,"500M");//水平轴
    painter.drawText(rect.left()-8,rect.bottom()+15,"O");//原点
//将每个数据用点表示
     QPoint points[2048];//设置drawdata_count个点去表示drawdata的drawdata_count个数据
     for(int i=0;i<2048;i++)
        {
          //两点的间隔为500M/2048个点
           float M=500;
           float point=2048;
           float interval=M/point;
           points[i].setX(i*interval+rect.left());

           //points[i].setY(drawdata[i]*(rect.height())/maxY+rect.top()+y*2);//sin函数时
           float proportion=1000;
           float Y=drawdata[i]/proportion;//将Y值根据坐标值比例缩小
           points[i].setY(rect.bottom()-Y);//从原点开始画
        }
           painter.setPen(Qt::red);
           painter.drawPoints(points, 2048);//绘制这些点

     //将每个点连接起来画折线图
       int x1,y1,x2,y2;
       x1=points[0].x();
       y1=points[0].y();
       for(int i=1;i<2048;i++)
       {
          x2=points[i].x();
          y2=points[i].y();
          painter.setPen(Qt::red);
          painter.drawLine(x1,y1,x2,y2);
          x1=x2;y1=y2;//进行交换,让折线图能够连接起来
       }

}

四、实时动态更新波形

 //利用定时器实时刷新图片
    /*定时器是用来处理周期性事件的一种对象,类似于硬件定时器。例如设置一个定时器的定时周期为1000毫秒,
     那么每1000毫秒就会发射定时器的timeout()信号,在信号关联的槽函数里就可以做相应的处理。*/
    timer = new QTimer(this);
    connect( timer, SIGNAL(timeout()), this, SLOT(flushBuff()));
    timer->start(2000);//启动或者重启服务器,msec(10000)为时间间隔,表示10s,没有参数时,时间间隔为0.
//实时刷新图片的槽函数
void myDialog::flushBuff()
{
      /*滚动刷新*/
//    unsigned int tmp = drawdata[0];
//    for(int i=0; i<count-1; i++ )
//    {
//    drawdata[i] = drawdata[i+1];
//    }
//    drawdata[count-1] = tmp;//保留数据
    /*全屏替代刷新*/
    slot=0;//清空计数
    for(int i=0; i<2048; i++ )//将第一组2048个数据存入一个缓冲器内部
    {
       drawdata_buffer[i] = drawdata[i];
    }
    for(int j=0;j<valid-1;j++)
    {
        for(int i=0; i<2048; i++ )
        {
           drawdata[i+2048*slot] = drawdata[i+2048*(slot+1)];
        }
        slot++;
    }
    for(int i=0; i<2048; i++ )//将缓冲器内部的数据给最后一个组,进行交替
    {
       drawdata[i+2048*slot] = drawdata_buffer[i];
    }
    update();//update()调用绘图事件来实现画面更新,更新界面

}

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值