基于Qt的信号分析简单应用软件的设计
一、需求描述:
1、读取data.asc文件,分析其连续性;
2、绘制信号图像,并保存。
二、UI界面组成:
该应用的UI由以下几个控件组成:
3个PushButton:打开文件、图像保存、退出;
1个Combox:下拉框用于信号的选择;
1个Widget:用于确定绘图区域的坐标,并在Widget部件上绘制图像曲线。
3个Label:用于标注注释,及坐标轴
三、主要功能的实现
信号分析结果如下:
其中最主要的涉及信号数据的标准化处理,标准化处理计算公式:
std=(当前信号值—此类信号的最小值)/(此类信号的最大值—此类信号的最小值)
1、坐标轴的绘制
void Dialog::paintEvent(QPaintEvent *event)//重绘事件处理函数的定义 实现绘制坐标轴函数 { QPainter painter(this);//创建一个QPainter对象,this为绘图设备 QPoint wpostion = ui->widget->pos(); //当前窗体Widget的原点的位置,weight的左上角处(0,0)点 QSize wsize = ui->widget->size(); //Ui窗体当前的大小(宽 高) //设置坐标轴点的坐标 int x1=wpostion.x()-1; //0-1 int y1= wpostion.y()+ wsize.height()+1 ; //0+高+1 //创建画笔P212 设画笔使用颜色 线宽 画笔风格 画笔端点风格 画笔连接风格 QPen pen(Qt::blue,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin); //使用画笔 painter.setPen(pen); //绘制坐标轴 painter.drawLine(x1,y1,this->width()-20,y1);//绘制横轴 时间轴 painter.drawLine(x1,wpostion.y(),x1,y1);//绘制纵轴 信号值轴 }
2、文件打开功能实现
void Dialog::on_filepushButton_clicked() //打开文件按钮函数的定义 实现文本文件的读取 { QString fileName = QFileDialog::getOpenFileName(this, tr("文件打开对话框"),"D", tr("文本文件(*.txt);;ASC文件(*.asc)")); //使用QFileDialog类中的getOpenFileName()函数获取选择的文件名 返回选择的文件的文件名 //参数定义 指定父窗口 设置对话框标题 指定打开目录路径 文件类型过滤器 QFile file(fileName);//创建一个QFile类对象, //然后以只读的方式打开 if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } int rownum=0;//第一行行号为0 for(int i=0;i<16;i++)//16列初始化 data[i].clear(); QTextStream in(&file);//一行一行的读取一个文本文件 while(!in.atEnd()) { QString fileLine=in.readLine(); //读取到每一行的字符串 //p327 对分行读取的字符串进行处理 QStringList sl=fileLine.split(" ",QString::SkipEmptyParts);//字符串分割 将分割后的字符串放入组表中 rownum++;//行号加1 int i=0; //第i列 //将每一行的各个元素 分别放入每一列对应下的数组内 for(QStringList::const_iterator it=sl.constBegin();it!=sl.end();it++,i++) //it每行字符组的个数 { data[i].push_back((*it).toFloat()); //将字符串转换成浮点数据写入数据容器内 } } ui->comboBox->setCurrentIndex(1); //下拉框当前值值第一列 }
3、图像保存功能
void Dialog::on_pushButton_2_clicked()//实现图像保存 { QPixmap pixmap;//定义一个pixmap图像 pixmap=pixmap.grabWindow(QApplication::desktop()->winId(),pos().x(),pos().y(),frameGeometry().width(),frameGeometry().height()); //grabWindow可以实现将屏幕上的窗体保存成一个QPixmap格式的图片 pixmap.save("D:\\picture.jpg","JPG");//将截取的窗体图像保存到E盘并以JPG格式保存 }
4、退出按钮的实现
void Dialog::on_pushButton_clicked()//退出当前窗口 { this->close(); }
5、曲线绘制事件
void Widget2::paintEvent(QPaintEvent *event)//重绘事件处理函数的定义 在widget部件上绘制曲线 { //信号值y值 接收 if(m_data==NULL) return; QVector<float>& data = *m_data; int r=0;//初始化行坐标为0 const int rnum=data.size();//每一列信号的值的个数 即行号 if(rnum==0) return; //如果当前没有信号值 返回 //信号值找最大值最小值的过程 float min,max; min=max=data[0]; for(int i=1;i<rnum;i++) { if(data[i]>max) max=data[i]; if(data[i]<min) min=data[i]; } //数据标准化过程 x=(x-min)/(max-min)*height const float wheight=this->height(); /*while(max!=min) { for(int j=0;j<rnum;j++) { data[j]=(data[j]-min)*wheight/(max-min); } } for(int j=0;j<rnum;j++) { if(max=min) { data[j]=wheight/2; } else { data[j]=(data[j]-min)*wheight/(max-min); } }*/ //设置路径path的过程 P230 QPainterPath path;//定义一个path对象 //曲线当前点 path.moveTo(r,max!=min?((data[r]-min)/(max-min))*wheight:wheight/2); //曲线目标点 即下一个点 下一个点自动变成当前点 for(r=1;r<rnum;r++) { path.lineTo(r,max!=min?((data[r]-min)/(max-min))*wheight:wheight/2); } //绘制曲线的过程 //指定绘图设备 QPainter painter(this); //创建画笔P212 设画笔使用颜色 线宽 画笔风格 画笔端点风格 画笔连接风格 QPen pen(Qt::red,1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin); //使用画笔 painter.setPen(pen); //将坐标系统进行平移 平移到起始点位置 painter.translate(0, this->height()); //将坐标系统进行缩放 painter.scale(1,-1); //绘制当前路径 painter.drawPath(path); }