Qt 实现脉搏检测-2,简陋的功能产品
今天终于可以接上硬件来显示真是的脉搏情况了,上图
主要就是显示脉搏的心跳曲线,和IBI
数据来源是三个,串口,网口和蓝牙,目前只实现了串口,过程应该都是差不多的,监听,读取,解析,等硬件更新后,再次更新代码
下面说说代买部分
#include "get_date.h" #include <windows.h> #include <QDebug> #include <QTimer> #include <QSerialPort> #include <QDebug> static int flag_get =0; QTimer timer; QSerialPort port; QSerialPort serialport; static int serialport_date = 0; static int bmp = 200; static int ibi = 0; Get_date::Get_date() { qDebug()<<"Qthread is run"; serialport.setPortName("COM4"); serialport.open(QIODevice::ReadWrite); serialport.setBaudRate(115200); serialport.setDataBits(QSerialPort::Data8); serialport.setParity(QSerialPort::NoParity); serialport.setStopBits(QSerialPort::OneStop); serialport.setFlowControl(QSerialPort::NoFlowControl); connect(&serialport,SIGNAL(readyRead()),this,SLOT(read_serialport())); } void Get_date::run() { connect(&timer,SIGNAL(timeout()),this,SLOT(timerout())); timer.start(100); } Get_date::~Get_date() { timer.stop(); qDebug()<<"Qthread is exit"; } void Get_date::change_get_flag(int temp) { flag_get = temp; } void Get_date::timerout() { switch (flag_get) { case 0: //串口 break; case 1: //网口 emit send_date(1,rand()%300,0,0,0); break; case 2: //蓝牙 emit send_date(2,rand()%300,0,0,0); break; default: break; } } static bool q_flag = true; void Get_date::read_serialport() { QByteArray temp; temp = serialport.readAll(); // qDebug()<<bmp<<temp; serialport_date = temp.mid(1,3).toInt(); if(temp.length()>6) { int temp1=0; if((temp1 = temp.indexOf("B"))>0) { QByteArray temp3 = temp.mid(temp1+1); int temp2 = temp3.indexOf("\r"); bmp = temp3.mid(0,temp2).toInt(); } if((temp1 = temp.indexOf("Q"))>0) { QByteArray temp3 = temp.mid(temp1+1); int temp2 = temp3.indexOf("\r"); ibi = temp3.mid(0,temp2).toInt(); q_flag = true; } else { q_flag = false; } } if(flag_get == 0) { if(q_flag) { emit send_date(0,serialport_date,bmp,ibi,1); } else { emit send_date(0,serialport_date,bmp,ibi,0); } } }
这部分目前只要就是从串口读取数据,但是现在有一个问题就是,每次串口的端口不是固定的,还没有找到好的方法来检测,等正式开发的时候可以检测id,现在目前只能是每次看一下,完了该一下代码中的端口号码。
还有一个问题不知道大家有没有遇到过,就是在默认窗口大小的时候,串口接受数据都是正常的,但是当我把窗口最大话的时候,串口接收的数据就会出现错误,
所以我代码里面用了关键字检索,而没有用格式化截取。
#include "palmus.h" #include "ui_palmus.h" #include <QDebug> #include <list> #include <windows.h> #include <QtMath> #include <QMovie> #include <QTimer> using namespace std; typedef list<int> LISTINT; static LISTINT listdate; static LISTINT::iterator i,j; static LISTINT ibidate; static LISTINT::iterator k,l; QMovie* movie; static int bmp = 599; Palmus::Palmus(QWidget *parent) :QWidget(parent), ui(new Ui::Palmus) { ui->setupUi(this); this->setWindowTitle("Palmus"); ui->label_palmus->setStyleSheet("background-color: rgb(0, 0, 0)"); ui->label_palmus->installEventFilter(this); ui->label_ibi->installEventFilter(this); connect(&Demodate,SIGNAL(send_date(int,int,int,int,int)),this,SLOT(slot_get_date(int,int,int,int,int))); connect(this,SIGNAL(get_date_flag(int)),&Demodate,SLOT(change_get_flag(int))); movie = new QMovie("D:/WorkSpace/Palmus/source/heart_gif_2.gif"); ui->label_heart->setMovie(movie); movie->start(); Demodate.run(); ui->label_blue->hide(); ui->label_blue_date->hide(); ui->label_internet->hide(); ui->label_internet_date->hide(); ui->label_serial->hide(); ui->label_serial_date->hide(); } Palmus::~Palmus() { movie->stop(); Demodate.exit(1); delete ui; } static bool serial_flag = true; static bool interent_flag = true; static bool blue_flag = true; void Palmus::slot_get_date(int temp1, int temp2, int temp3, int temp4, int temp5) { switch (temp1) { case 0: { ui->label_blue->hide(); ui->label_blue_date->hide(); ui->label_internet->hide(); ui->label_internet_date->hide(); ui->label_serial->show(); if(serial_flag) { ui->label_serial_date->show(); serial_flag = false; } else { ui->label_serial_date->hide(); serial_flag = true; } listdate.push_front(0-(temp2-512)); bmp = temp3; if(temp5 ==1) { ibidate.push_front(temp4); } update(); if(listdate.size()>999) { listdate.pop_back(); } if(ibidate.size()>999) { ibidate.pop_back(); } break; } case 1: { ui->label_blue->hide(); ui->label_blue_date->hide(); ui->label_internet->show(); ui->label_serial->hide(); ui->label_serial_date->hide(); if(interent_flag) { ui->label_internet_date->show(); interent_flag = false; } else { ui->label_internet_date->hide(); interent_flag = true; } listdate.push_front(temp2); update(); if(listdate.size()>999) { listdate.pop_back(); } break; } case 2: { ui->label_blue->show(); ui->label_internet->hide(); ui->label_internet_date->hide(); ui->label_serial->hide(); ui->label_serial_date->hide(); if(blue_flag) { ui->label_blue_date->show(); blue_flag = false; } else { ui->label_blue_date->hide(); blue_flag = true; } listdate.push_front(temp2); update(); if(listdate.size()>999) { listdate.pop_back(); } break; } default: break; } } bool Palmus::eventFilter(QObject *object1, QEvent *event1) { if(object1 == ui->label_palmus&&event1->type()==QEvent::Paint) { draw_palmus(); } if(object1 == ui->label_ibi&&event1->type()==QEvent::Paint) { draw_ibi(); } return true; } static int temp1; static int temp2; void Palmus::draw_palmus() { //Draw scale QPainter painter_scale(ui->label_palmus); painter_scale.setBrush(Qt::black); painter_scale.drawRect(0,0,ui->label_palmus->width(),ui->label_palmus->height()); painter_scale.setPen(QPen(Qt::green,0.5)); painter_scale.setRenderHints(QPainter::Antialiasing,true); int scale_x = ui->label_palmus->width(); int scale_y = ui->label_palmus->height(); painter_scale.drawLine(0,0,0,scale_y); painter_scale.drawLine(0,scale_y,scale_x,scale_y); while (scale_y>0) { painter_scale.drawLine(0,scale_y,ui->label_palmus->width(),scale_y); scale_y = scale_y-20; } scale_x = 0; scale_y = ui->label_palmus->height(); while (scale_x<(ui->label_palmus->width())) { painter_scale.drawLine(scale_x,scale_y,scale_x,0); scale_x= scale_x+20; } //Draw palmus QPainter painter(ui->label_palmus); painter.setRenderHints(QPainter::Antialiasing,true); painter.translate(0,(ui->label_palmus->height()/2)); painter.save(); painter.setPen(QPen(Qt::red,2)); int x = ui->label_palmus->width(); i = listdate.begin(); temp1 = *i; for(i=listdate.begin();i!=listdate.end();i=i.operator ++(1)) { j=i.operator ++(1); temp2 = *j; painter.drawLine(x,(ui->Slider_scale->value()/100.0)*(temp1/1024.0*ui->label_palmus->height()),x-3,(ui->Slider_scale->value()/100.0)*(temp2/1024.0*ui->label_palmus->height())); temp1 = temp2; x=x-3; } bmp = min(bmp,200); ui->label_heart_rate->setText("BMP:"+QString::number(bmp,10)); painter.restore(); } void Palmus::draw_ibi() { QPainter painter(ui->label_ibi); painter.setPen(QPen(Qt::red,2)); int x = ui->label_ibi->width(); k = ibidate.begin(); temp1 = *k; float temp3 =1024.0; for(k=ibidate.begin();k!=ibidate.end();k=k.operator ++(1)) { l=k.operator ++(1); temp2 = *l; if(temp1>temp3) { temp3 = temp1/1.0; } painter.drawLine(x,(temp1/temp3*ui->label_ibi->height()),x-1,(temp2/temp3*ui->label_ibi->height())); temp1 = temp2; x=x-1; } ui->label_ibi_date->setText("IBI:"+QString::number(*ibidate.begin(),10)); } //void Palmus::draw_heart() //{ // QPainter painter(ui->label_heart); // double x, y, r; // for (int i = 0; i <= 90; i++) // { // for (int j = 0; j <= 90; j++) // { // //转换为直角坐标系,设置偏移量,使图像居中 // r = M_PI / 45 * i * (1 - qSin(M_PI / 45 * j)) * 19; // x = r * qCos(M_PI / 45 * j) * qSin(M_PI / 45 * i) + 100 / 2; // y = -r * qSin(M_PI / 45 * j) + 100 / 4; // painter.setBrush(Qt::red); // painter.setPen(Qt::red); // painter.drawPoint(x,y); // } // } //} void Palmus::on_pushButton_clicked() { listdate.clear(); update(); emit get_date_flag(0); } void Palmus::on_pushButton_2_clicked() { listdate.clear(); update(); emit get_date_flag(1); } void Palmus::on_pushButton_3_clicked() { listdate.clear(); update(); emit get_date_flag(2); }
这部分目前也没有做太多的修改,因为没有网络和蓝牙部分的代码,所以好多逻辑还是有问题,需要在正式开的时候重新梳理一下逻辑,现在也指示能够勉强实现。如果有那里有疑问可以联系我,或者有更好的解决方案可以直接找我,欢迎大神们指导,哈哈。
界面问题,以前都不怎么会用界面的布局,一般写的也都是嵌入式设备的程序,用的最多的就是全屏显示,剩下的就是绝对布局了。
这次逼着这几学习了一下布局,发现用了就会爱上它,哈哈哈
用了几个布局的,感觉用布局,那你就要提前都想的差不多了,后期在加,感觉好有困难的,也许还是自己用的不熟练,弄了好几次才勉强可以使用了,以后希望可以尝试更多的布局。
源代码连接在后期评论中加上