logo资料库

基于Qt5实现的心率变异与心率减速力分析软件源代码.docx

第1页 / 共44页
第2页 / 共44页
第3页 / 共44页
第4页 / 共44页
第5页 / 共44页
第6页 / 共44页
第7页 / 共44页
第8页 / 共44页
资料共44页,剩余部分请下载后查看
1)数据库模块
(1)头文件database.h
#include
#include
#include
#include
#include
#include
#include
class DataBase
{
public:
DataBase();
//数据库初始化函数
void DataBaseInit();
//数据库查询函数
QString SelectFilePath(QString select,char* si
public:
//模型变量
QStandardItemModel* model;
private:
//条目变量
QStandardItem* item;
};
#endif // DATABASE_H
(2)类文件database.cpp
#include "database.h"
DataBase::DataBase(){}
/* 函数名:DataBaseInit()
* 参 数:无
* 作 用:连接数据库,导入数据
* 建立数据库视图
* */
void DataBase::DataBaseInit()
{
//添加SQlite数据库
QSqlDatabase db=QSqlDatabase::addDatabase("QSQ
//设置数据库
db.setDatabaseName("../EcgData.db");
//打开数据库
if(!db.open())//数据库打开失败
{
QMessageBox::warning(this,QString::fromLoc
return;
}
QSqlQuery query;
bool sign1=query.exec("create table EcgData("
"FID int primary key not
"FNAME char(100),"
"FPATH char(500),"
"FHEA char(300),"
"FDAT char(300),"
"FATR char(300));");
bool sign2=query.exec("insert into EcgData val
"(1,'16265','E:/Qt5.11.1/ChengXu/MyP
"(2,'16272','E:/Qt5.11.1/ChengXu/MyP
"(3,'16273','E:/Qt5.11.1/ChengXu/MyP
"(4,'16420','E:/Qt5.11.1/ChengXu/MyP
"(5,'16483','E:/Qt5.11.1/ChengXu/MyP
"(6,'100','E:/Qt5.11.1/ChengXu/MyPro
"(7,'101','E:/Qt5.11.1/ChengXu/MyPro
"(8,'102','E:/Qt5.11.1/ChengXu/MyPro
"(9,'103','E:/Qt5.11.1/ChengXu/MyPro
bool sign3=query.exec("select * from EcgData")
//创建标准模型
model=new QStandardItemModel;
item=new QStandardItem;
item->setText("File");
model->setHorizontalHeaderItem(0,item);
//获取模型的根项(Root Item),根项是不可见的
QStandardItem* parentItem=model->invisibleRoot
qDebug()<
while(query.next())
{
//创建标准项item0,并设置显示文本,图标和工具提示
QStandardItem* itemFname=new QStandardItem
QStandardItem *itemFhea=new QStandardItem;
QStandardItem *itemFdat=new QStandardItem;
QStandardItem *itemFatr=new QStandardItem;
itemFname->setText(query.value("FNAME").to
itemFname->setIcon(QIcon(":/Image/image/li
itemFname->setToolTip("indexA");
//将创建的标准项作为根项的子项
parentItem->appendRow(itemFname);
//将创建的标准项作为新的父项
parentItem=itemFname;
itemFhea->setText(query.value("FHEA").toSt
itemFhea->setIcon(QIcon(":/Image/image/exp
itemFdat->setText(query.value("FDAT").toSt
itemFdat->setIcon(QIcon(":/Image/image/ECG
itemFatr->setText(query.value("FATR").toSt
itemFatr->setIcon(QIcon(":/Image/image/atr
itemFname->appendRow(itemFhea);
itemFname->appendRow(itemFdat);
itemFname->appendRow(itemFatr);
//获取模型的根项
parentItem=model->invisibleRootItem();
}
}
/* 函数名:SelectFilePath(QString select,char* sign)
* 参 数:QString select为用户点击选择的文件名
* char* sign文件名标记
* 作 用:查询用户选择的文件,返回文件地址
* */
QString DataBase::SelectFilePath(QString select,ch
{
QString name=select.mid(0,select.length()-4);
QSqlQuery query;
if(*sign=='h')
{
query.exec(QString("select FPATH from EcgD
while(query.next())
return query.value("FPATH").toString()
}
else if(*sign=='d')
{
query.exec(QString("select FPATH from EcgD
while(query.next())
return query.value("FPATH").toString()
}
else if(*sign=='a')
{
query.exec(QString("select FPATH from EcgD
while(query.next())
return query.value("FPATH").toString()
}
else
return NULL;
return NULL;
}
2)文件协议模块
(1)头文件函数openfile.h
#ifndef OPENFILE_H
#define OPENFILE_H
#include
#include
#include
#include
#include
class OpenFile
{
public:
struct HEA
{
HEA() {}
int FileNumber=0;//文件编号
int SignalNumber=0;//信号个数
double SamplingFrquemcy=0;//采样频率
int SignalLength=0;//每一信号长度
QString SamplinTime=NULL;//采样时间
QString FileName1=NULL;//信号1技术规划范说明文件名
QString Format1=NULL;//压缩格式
double Gain1=0;//增益
int ADC1=0;//ADC分辨率
int Baseline1=0;//基线
int FirstValue1=0;//第一采样点初值
int CheckNumber1=0;//校验数
int IO1=0;//输入输出
QString File1=0;//文件1
QString FileName2=0;//信号2技术规划范说明文件名
QString Format2=0;//压缩格式
double Gain2=0;//增益
int ADC2=0;//ADC分辨率
int Baseline2=0;//基线(ADC零值)
int FirstValue2=0;//第一采样点初值
int CheckNumber2=0;//校验数
int IO2=0;//输入输出
QString File2=NULL;//文件2
QString Annotation1=NULL;//注释
};
HEA* hea;
void Hea(int sign,QString str);
//函数定义区
public:
//构造函数
OpenFile();
//析构函数
~OpenFile();
//读取hea文件,并将hea文件数据转换为采样信息和患者基本信息
void HEAtoString(const char* HeaFilePath);//参数
//读取dat文件,并将dat数据转换为幅值
void DATtoSignalAmplitude(const char* DatFileP
//读取atr文件,并将atr数据转换为幅值
void ATRtoRRInterval(const char *AtrFilePath);
//打开文件对话框,并返回文件名
QString fileDialog(QWidget* parent);
//判断文件大小函数
int fileSize(FILE* filename);
//打开文件并将文件读入malloc内存
bool OpenFileToMalloc(const char* FilePath);
//变量定义区
public:
//定义文件大小
uint file_Size;
//定义每组数据大小
uint data_Size;
//采样信号1/2幅值内存存储头指针
double* p_sigal_amplitude_value1;
double* p_sigal_amplitude_value2;
//定义RR间期数组,索引值为第几个波峰,存储数值为距离上一个波峰的时间ms
double* p_RR_Interval=NULL;
QVectorR_Wave;
//定义RR间期数组的长度
uint RR_intervalLength=0;
//输出信息
QStringList OpenFileList;
//RR剔除率
double RREliminatingRate=0.0;
private:
//定义文件指针
FILE* pFile;
//定义读取数据是否成功的标志位
int fileReadIsSucceed;
//定义pFile文件在malloc动态内存中分配空间的首地址
char* file_malloc_address;
};
#endif // OPENFILE_H
(2)将文件导入内存函数:
/*函数名:OpenFileToMalloc
*参 数:char* FilePath为文件的路径
*作 用:打开文件并将文件读入malloc内存
* 为file_Size赋值,即文件大小可以使用
* 为file_malloc_address赋值,即文件已经读入内存
* */
bool OpenFile::OpenFileToMalloc(const char* FilePa
{
//1.打开文件
pFile = fopen(FilePath, "r");
if (!pFile)
{
OpenFileList<
return false;
}
else{
OpenFileList<
}
//2.判断文件大小
file_Size = fileSize(pFile);//返回文件大小
//3.申请dat文件所需内存空间
file_malloc_address = (char*)malloc(file_Size)
if (!file_malloc_address)
{
OpenFileList<
return false;
}
else{
OpenFileList<
}
memset(file_malloc_address, 0, file_Size);//初始
//4.读取dat文件中数据,写入内存空间
fseek(pFile, 0, SEEK_SET);//将文件指针指向文件开始
fileReadIsSucceed = fread(file_malloc_address,
if (!fileReadIsSucceed)
{
OpenFileList<
return false;
}
else{
OpenFileList<
}
//5.关闭文件
fclose(pFile);
return true;
}
(3)读取hea文件函数:
/*函数名:HEAtoString
*参 数:char *HeaFilePath为文件的路径
*作 用:提取hea头文件有用信息
* */
void OpenFile::HEAtoString(const char *HeaFilePath
{
file_Size=0;
if(!OpenFileToMalloc(HeaFilePath))
return;
hea=new HEA;
QString str;
int sign=0;
int i=0;
for(i;sign<23;i++)
{
while(sign<5)
{
//qDebug()<<"sign:"<
if(*(file_malloc_address+i)=='\n')
{
Hea(sign,str);
str.clear();
sign=5;
i++;
break;
}
else if((*(file_malloc_address+i)==' '
{
//qDebug()<<" sign:"<
Hea(sign,str);
sign++;
i++;
str.clear();
}else
str+=(*(file_malloc_address+i++));
}
//qDebug()<<"sign2"<
if((*(file_malloc_address+i)==' ')|(*(file
{
Hea(sign,str);
sign++;
str.clear();
}else
str+=(*(file_malloc_address+i));
}
for(i;i
str+=(*(file_malloc_address+i));
hea->Annotation1=str;//注释
free(file_malloc_address);
}
void OpenFile::Hea(int sign,QString str)
{
switch (sign) {
case 0:
hea->FileNumber=str.toInt();//文件编号
break;
case 1:
hea->SignalNumber=str.toInt();//信号个数
break;
case 2:
hea->SamplingFrquemcy=str.toDouble();//采样频
break;
case 3:
hea->SignalLength=str.toInt();//每一信号长度
break;
case 4:
hea->SamplinTime=str;//采样时间
//qDebug()<<"4"<SamplinTime;
break;
case 5:
hea->FileName1=str;//信号1技术规划范说明文件名
break;
case 6:
hea->Format1=str;//压缩格式
break;
case 7:
hea->Gain1=str.toDouble();//增益
break;
case 8:
hea->ADC1=str.toInt();//ADC分辨率
break;
case 9:
hea->Baseline1=str.toInt();//基线
break;
case 10:
hea->FirstValue1=str.toInt();//第一采样点初值
break;
case 11:
hea->CheckNumber1=str.toInt();//校验数
break;
case 12:
hea->IO1=str.toInt();//输入输出
break;
case 13:
hea->File1=str;//文件1
break;
case 14:
hea->FileName2=str;//信号2技术规划范说明文件名
break;
case 15:
hea->Format2=str;//压缩格式
break;
case 16:
hea->Gain2=str.toDouble();//增益
break;
case 17:
hea->ADC2=str.toInt();//ADC分辨率
break;
case 18:
hea->Baseline2=str.toInt();//基线(ADC零值)
break;
case 19:
hea->FirstValue2=str.toInt();//第一采样点初值
break;
case 20:
hea->CheckNumber2=str.toInt();//校验数
break;
case 21:
hea->IO2=str.toInt();//输入输出
break;
case 22:
hea->File2=str;//文件2
break;
default:
break;
}
}
(4)读取dat文件函数:
(5)读取atr文件函数:
(6)文件对话框函数
3)心率变异分析模块
(1)头文件hrvanalyze.h
#ifndef HRVANALYZE_H
#define HRVANALYZE_H
class HRVAnalyze
{
public:
HRVAnalyze(double* pRR,int length);
//HRVAnalyze初始化函数
void HRVAnalyzeInit();
double getSDNN();
double getRMSSD();
double getSDSD();
double getpNN10();
double getpNN20();
double getpNN30();
double getpNN40();
double getpNN50();
double getpNN60();
double getpNN70();
private:
double* pRR;
int length;
double SDNN;//所有的窦性心搏R-R(N-N)间期的标准差
double RMSSD;//相邻N-N间期差值的均方根,将所有值平方求和,求其均值,再开平
double SDSD;//相邻N-N间期差值的标准差
double RRAverageValue;
double RRDifferenceAverage;
double* RRDifference;//RR间期差值数组
double pNN10;//|(Rn-(RR平均值))|<10的个数除以RR间期的总数
double pNN20;
double pNN30;
double pNN40;
double pNN50;
double pNN60;
double pNN70;
};
#endif // HRVANALYZE_H
(2)函数文件hrvanalyze.cpp
#include "hrvanalyze.h"
#include
#include
#include
HRVAnalyze::HRVAnalyze(double *pRR, int length)
{
this->pRR=pRR;
this->length=length;
SDNN=0.0;//所有的窦性心搏R-R(N-N)间期的标准差
RMSSD=0.0;//相邻N-N间期差值的均方根
SDSD=0.0;//相邻N-N间期差值的标准差
pNN10=0.0;//|(Rn-(RR平均值))|<10的个数除以RR间期的总数
pNN20=0.0;
pNN30=0.0;
pNN40=0.0;
pNN50=0.0;
pNN60=0.0;
pNN70=0.0;
RRDifference=NULL;
RRAverageValue=0.0;
RRDifferenceAverage=0.0;
HRVAnalyzeInit();
}
//HRVAnalyze初始化函数
void HRVAnalyze::HRVAnalyzeInit()
{
//有length个RR间期,所以有length-1个RR间期差值
RRDifference=(double*)malloc(sizeof(double)*(l
double diff=0.0;
for(int i=0;i
{
diff=pRR[i+1]-pRR[i];//求RR间期差值
if(diff<0)diff=0.0-diff;
RRDifference[i]=diff;
RRDifferenceAverage+=diff;//求RR间期差值的所有的和,以
RRAverageValue+=*(pRR+i);//求RR间期的所有的和,以便求R
int sign=((int)diff)/10;//判断RR间期差值的范围区间
switch (sign) {
case 10:
case 9:
case 8:
case 7:
pNN70+=1;
case 6:
pNN60+=1;
case 5:
pNN50+=1;
case 4:
pNN40+=1;
case 3:
pNN30+=1;
case 2:
pNN20+=1;
case 1:
pNN10+=1;
break;
default:
break;
}
}
RRDifferenceAverage/=(length-1);//RR间期差值的平均值
RRAverageValue+=pRR[length-1];//RR间期和。上面的循环中漏掉
RRAverageValue/=length;//求出RR间期平均值
}
//所有的窦性心搏R-R(N-N)间期的标准差
double HRVAnalyze::getSDNN()
{
//1.求所有RR间期与平均RR间期的差值的平方的和
for(int i=0;i
{
SDNN+=(*(pRR+i)-RRAverageValue)*(*(pRR+i)-
}
//2.求平方和的平均值
SDNN/=length;
//3.开方,得到SDDN
SDNN=sqrt(SDNN);
return SDNN;
}
//相邻N-N间期差值的均方根
double HRVAnalyze::getRMSSD()
{
//1.将所有值平方求和,再开平方,就得到均方根值
for(int i=0;i
RMSSD+=(RRDifference[i]*RRDifference[i]);
//2.求其均值
RMSSD/=(length-1);
//3.开方
RMSSD=sqrt(RMSSD);
return RMSSD;
}
//相邻N-N间期差值的标准差
double HRVAnalyze::getSDSD()
{
double temp=0.0;
//2.求所有(RR间期差值)与(RR间期的平均值)的差值的平方的和
for(int i=0;i
{
temp=RRDifference[i]-RRDifferenceAverage;
temp=temp*temp;
SDSD+=temp;
}
//3.开方得到SDSD
SDSD=sqrt(SDSD/(length-1));
return SDSD;
}
double HRVAnalyze::getpNN10(){return pNN10/(length
double HRVAnalyze::getpNN20(){return pNN20/(length
double HRVAnalyze::getpNN30(){return pNN30/(length
double HRVAnalyze::getpNN40(){return pNN40/(length
double HRVAnalyze::getpNN50(){return pNN50/(length
double HRVAnalyze::getpNN60(){return pNN60/(length
double HRVAnalyze::getpNN70(){return pNN70/(length
4)心率减速力分析模块
(1)头文件dcanalyze.h
class DCAnalyze
{
//函数定义区
public:
//构造函数
DCAnalyze();
//析构函数
~DCAnalyze();
//计算DC/AC值的函数
void DC_Data(double* pRR, unsigned int RR_inte
//变量定义区
public:
//存储单一有用RR间期的结构体
struct RR_DC
{
int sign=0;//DC,AC信号的判定标记值(DC减速力为0,AC加速力为1
double value=0;//该值的大小
};
//存储所有的RR间期的可变数组
QVectorRR_DC_Vector;
//DC/AC中心信号的平均值
double DC_AverageValue[31]={0.0};
double AC_AverageValue[31]={0.0};
//DC/AC心率段的个数
int DC_length=0;
int AC_length=0;
//DC/AC值
double DC=0.0;
double AC=0.0;
};
#endif // DCANALYZE_H
(2)函数文件dcanalyze.cpp
#include "dcanalyze.h"
#include
#include
DCAnalyze::DCAnalyze(){}
DCAnalyze::~DCAnalyze(){}
/* 函数名:DC_Data
* 参 数:double *pRR为RR间期数据的指针
* unsigned int RR_intervalLength为RR间期指针的长度
* 作 用:计算DC/AC图像中各个点的值存储到DC_AverageValue[31]、DC_A
* 计算DC、AC的值
* */
void DCAnalyze::DC_Data(double *pRR, unsigned int
{
//清空上一次函数调用时计算的值
memset(AC_AverageValue,0.0,31);
memset(DC_AverageValue,0.0,31);
AC_length=0;
DC_length=0;
RR_DC_Vector.clear();
RR_DC temp;//临时变量,用于存储过程中的RR值和sign信号
//1.确定减速周期加速周期,并做标记
for(unsigned int i=1;i
{
//判断是加速还是减速
if(*(pRR+i)<*(pRR+i-1))
{
temp.sign=1;//减速标志
temp.value=*(pRR+i);
RR_DC_Vector.append(temp);
}else {
temp.sign=0;//加速标志
temp.value=*(pRR+i);
RR_DC_Vector.append(temp);
}
}
qDebug()<<"RR_DC_Vector.length()"<
//2.各心率段的位相整序,以入选的加速点或减速点为中心,进行不同心率段的有序排列
for(int i=15;i
{
if(RR_DC_Vector.at(i).sign==0)//如果为减速力
{
DC_length++;//减速力段的个数加一
for(int j=-15;j<=15;j++)//将该段31个数据与以前相
DC_AverageValue[j+15]+=RR_DC_Vecto
}
else//如果为加速力
{
AC_length++;//加速力段的个数加一
for(int j=-15;j<=15;j++)//将该段31个数据与以前相
AC_AverageValue[j+15]+=RR_DC_Vecto
}
}
//3.对应序号的周期进行信号平均
for(int i=0;i<31;i++)
{
DC_AverageValue[i]/=DC_length;
AC_AverageValue[i]/=AC_length;
}
qDebug()<<"DC_length:"<
//4.计算AC、DC值
DC=(DC_AverageValue[15]+DC_AverageValue[16]-DC
AC=(AC_AverageValue[15]+AC_AverageValue[16]-AC
}
5)绘图模块
(1)头文件chartsinit.h
(2)绘制心电图
(3)RR间期趋势图
(4)RR散点图
(5)RR差值散点图
(6)RR直方图
(7)RR差值直方图
(8)DC分析图
(9)AC分析图
6)按钮功能及菜单设计
(1)头文件mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include "chartsinit.h"
#include "openfile.h"
#include "dcanalyze.h"
#include "database.h"
#include "hrvanalyze.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
//函数定义区
public:
//构造函数
explicit MainWindow(QWidget *parent = 0);
//析构函数
~MainWindow();
//TabWindows最大化函数
void TabWindows(int ButtonMax);
private slots:
//ECG窗口TabWindows窗口最大化按钮槽函数
void on_ECG_MaxButton_toggled(bool checked);
//ECG窗口开始滚动显示心电图按钮
void on_ECG_StartButton_toggled(bool checked);
//RR间期开始滚动按钮
void on_RRTrend_StartButton_toggled(bool check
//ECG定时器溢出处理函数1,处理从左向右一直滚动
void ECG_onTimeOut();
//ECG定时器溢出处理函数2,处理从左向右滚动到达最右后,再次从左向右滚动
void ECG_onTimeOut2();
//RR_Trend定时器溢出处理函数
void RR_Trend_onTimeOut();
//RR_Poincare_Plot散点图将数据导入系列函数
void RR_Poincare_Plot();
//Differences_RR_Poincare_Plot差值散点图
void Differences_RR_Poincare_Plot();
//RR_Histogram直方图
void RR_Histogram();
//Differences_RR_Histogram差值直方图
void Differences_RR_Histogram();
//DC心率减速力图
void DC();
//AC心率加速力图
void AC();
//listWidget程序运行说明信息显示函数
void ListWidgetShow();
//双击打开hea文件函数
void OpenHea();
//双击打开dat文件函数
void OpenDat();
//双击打开atr文件函数
void OpenAtr();
//数据库视图双击函数
void on_treeView_doubleClicked(const QModelInd
//ECG绘图方式选择函数
void on_ECG_Painting_comboBox_currentIndexChan
//ECG背景选择函数
void on_ECG_Background_comboBox_currentIndexCh
//ECG绘图曲线颜色选择函数
void on_ECG_PenColor_comboBox_currentIndexChan
//ECG曲线走速选择函数
void on_ECG_WalkSpeed_spinBox_valueChanged(int
//ECG曲线线宽选择函数
void on_ECG_PenWidth_spinBox_valueChanged(int
//ECG网格线颜色选择函数
void on_ECG_GridLines_comboBox_currentIndexCha
//ECG题目字体选择函数
void on_ECG_Tiltle_fontComboBox_currentFontCha
//ECG题目颜色选择函数
void on_ECG_TitleColor_pushButton_clicked();
//ECG-X轴标注字体选择函数
void on_ECG_Xlabel_fontComboBox_currentFontCha
//ECG-Y轴标注字体选择函数
void on_ECG_Ylabel_fontComboBox_currentFontCha
//ECG-X轴标注颜色选择函数
void on_ECG_XlabelColor_pushButton_clicked();
//ECG-Y轴标注颜色选择函数
void on_ECG_Ylabel_pushButton_clicked();
//ECG-X轴标注更改函数
void on_ECG_Xlabel_lineEdit_returnPressed();
//ECG-Y轴标注更改函数
void on_ECG_Ylabel_lineEdit_returnPressed();
//ECG-X轴网格线可见函数
void on_ECG_XGridLineVisible_button_toggled(bo
//ECG-Y轴网格线可见函数
void on_ECG_YGridLineVisible_button_toggled(bo
//ECG-X轴标注字体大小函数
void on_ECG_XLabelFontSize_comboBox_currentInd
//ECG-Y轴标注字体大小函数
void on_ECG_YLabelFontSize_comboBox_currentInd
//HRV开始运行函数
void on_HRV_AnalyzeButton_clicked();
//DC开始运行函数
void on_DC_AC_Analyze_button_clicked();
void on_HRV_Background_comboBox_currentIndexCh
void on_HRV_GridLines_comboBox_currentIndexCha
void on_HRV_Painting_comboBox_currentIndexChan
void on_HRV_PenColor_comboBox_currentIndexChan
void on_HRV_PenWidth_spinBox_valueChanged(int
void on_HRV_WalkSpeed_spinBox_valueChanged(int
void on_HRV_XLabel_lineEdit_returnPressed();
void on_HRV_XLabelFontSize_comboBox_currentTex
void on_HRV_XGridLineVisible_Button_toggled(bo
void on_HRV_Ylabel_lineEdit_returnPressed();
void on_HRV_YLabelFontSize_comboBox_currentInd
void on_HRV_YGridLineVisible_Button_toggled(bo
void on_actionDCM_toggled(bool arg1);
void on_actionECG_triggered();
void on_actionRR_triggered();
void on_actionHRV_triggered();
void on_actionDC_triggered();
void on_actionExit_triggered();
void on_actionOpen_triggered();
void on_actionHA_triggered();
void on_actionHH_triggered();
void on_actionHD_triggered();
protected:
void SetShowModel(int value);
QFont SetFontAndSize(QFont f, float size);
void InitHRVpNNandTD();
void SetHRVpNNandTD();
void SetDcAcParameter();
void ECGInitButton();
void HRVInitButton();
//变量定义区
private:
Ui::MainWindow *ui;
//定义ChartsInit变量
ChartsInit* myChart=new ChartsInit;
//定义OpenFile变量
OpenFile* myFile=new OpenFile;
//定义DCAnalyze变量
DCAnalyze* DCData=new DCAnalyze;
//定义DataBase数据库变量
DataBase* myDataBase=new DataBase;
//定义HRVAnalyze变量
HRVAnalyze* myHRVAnalyze;
//定义ECG跳过数据的数量
uint ECG_nSkip=0;
//定义RR间期趋势图跳过数据的数量
uint RR_Trend_nSkip=0;
uint RR_Histogram_RRNumber[3000]={0};
uint DifferencesRR_Histogram_RRNumber[4000]={0
};
#endif // MAINWINDOW_H
(2)函数文件mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
QT_CHARTS_USE_NAMESPACE
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowState(Qt::WindowMaximized);//主窗
ui->ECG_graphicsView->setRenderHint(QPainter::
ui->RRTrend_graphicsView->setRenderHint(QPaint
ui->RR_Poincare_Plot_1->setRenderHint(QPainter
ui->Differences_RR_Poincare_Plot_2->setRenderH
ui->RR_Histogram_3->setRenderHint(QPainter::An
ui->Differences_RR_Histogram_4->setRenderHint(
ui->DC_graphicsView->setRenderHint(QPainter::A
ui->AC_graphicsView->setRenderHint(QPainter::A
myDataBase->DataBaseInit();//初始化数据库
ui->treeView->setEditTriggers(0);//设置TreeView的
ui->treeView->setModel(myDataBase->model);//为T
//初始化图表
myChart->ECGChartInit();//初始化ECG图表
myChart->RRTrendChartInti();//初始化RR间期趋势表
myChart->RRPoincarePlotChartInti();//初始化RR散点图
myChart->DifferencesRRPoincarePlotChartInti();
myChart->RRHistogramChartInti();//初始化RR直方图
myChart->DifferencesRRHistogramChartInti();//初
myChart->DCChartInti();//初始化DC界面
myChart->ACChartInti();//初始化AC界面
//将图表与各自的GraphicsView绑定
ui->ECG_graphicsView->setChart(myChart->ECG_Ch
ui->RRTrend_graphicsView->setChart(myChart->RR
ui->RR_Poincare_Plot_1->setChart(myChart->RRPo
ui->Differences_RR_Poincare_Plot_2->setChart(m
ui->RR_Histogram_3->setChart(myChart->RRHistog
ui->Differences_RR_Histogram_4->setChart(myCha
ui->DC_graphicsView->setChart(myChart->DC_Char
ui->AC_graphicsView->setChart(myChart->AC_Char
//设置按钮
ECGInitButton();
HRVInitButton();
ui->DC_AC_Analyze_button->setEnabled(false);
myChart->ECG_Timer.setInterval(8);//设置ECG 为8ms
myChart->RRTrend_Timer.setInterval(10);//设置RR间
connect(&myChart->RRTrend_Timer,&QTimer::timeo
connect(&myChart->ECG_Timer,&QTimer::timeout,t
myChart->ECG_Series1->replace(myChart->ECG_ptr
}
MainWindow::~MainWindow()
{
delete ui;
}
//ECG界面按钮初始化函数
void MainWindow::ECGInitButton()
{
ui->ECG_StartButton->setEnabled(false);
ui->ECG_LastButton->setEnabled(false);
ui->ECG_NextButton->setEnabled(false);
ui->ECG_Painting_comboBox->setEnabled(false);
ui->ECG_WalkSpeed_spinBox->setEnabled(false);
}
//HRV界面按钮初始化函数
void MainWindow::HRVInitButton()
{
ui->HRV_Painting_comboBox->setEnabled(false);
ui->HRV_WalkSpeed_spinBox->setEnabled(false);
ui->RRTrend_StartButton->setEnabled(false);
ui->HRV_AnalyzeButton->setEnabled(false);
}
//ECG开始按钮
void MainWindow::on_ECG_StartButton_toggled(bool c
{
if(checked)
{
//1.开启定时器
myChart->ECG_Timer.start();
//2.显示开始图标
ui->ECG_StartButton->setIcon(QIcon(":/Imag
}
else {
//1.关闭定时器
myChart->ECG_Timer.stop();
//2.显示暂停图标
ui->ECG_StartButton->setIcon(QIcon(":/Imag
}
}
//RR趋势图开始按钮
void MainWindow::on_RRTrend_StartButton_toggled(bo
{
if(checked)
{
//1.开启定时器
myChart->RRTrend_Timer.start();
//2.显示开始图标
ui->RRTrend_StartButton->setIcon(QIcon(":/
qDebug()<<"start";
}
else {
//1.关闭定时器
myChart->RRTrend_Timer.stop();
//2.显示暂停图标
ui->RRTrend_StartButton->setIcon(QIcon(":/
qDebug()<<"stop";
}
}
//ECG定时器溢出函数1,动态显示心电图,从左向右滚动显示
void MainWindow::ECG_onTimeOut()
{
myChart->ECG_ptrNew.clear();
//myChart->ptrOld.clear();
for(int i=0;iECG_X_MaxSize;i++)
myChart->ECG_ptrNew.append(QPointF(i,*(myF
if(ECG_nSkip>=(myFile->file_Size/2-myChart->EC
myChart->ECG_Timer.stop();
else
{
ECG_nSkip++;
myChart->ECG_Series1->replace(myChart->ECG
}
}
//ECG定时器溢出处理函数2,处理从左向右滚动到达最右后,再次从左向右滚动
void MainWindow::ECG_onTimeOut2()
{
myChart->ECG_ptrNew.replace(ECG_nSkip%myChart-
if(ECG_nSkip>=(myFile->file_Size/2-myChart->EC
myChart->ECG_Timer.stop();
else
{
ECG_nSkip++;
myChart->ECG_Series1->replace(myChart->ECG_
}
}
//RR间期趋势图时间溢出函数,动态显示RR间期图
void MainWindow::RR_Trend_onTimeOut()
{
myChart->RRTrend_ptrNew.clear();
for(int i=0;i<300;i++)
{
myChart->RRTrend_ptrNew.append
(QPointF(i,*(myFile->p_RR_Interval
}
if(RR_Trend_nSkip>=myFile->RR_intervalLength-1
{
myChart->RRTrend_Timer.stop();
}
else
{
RR_Trend_nSkip+=1;
myChart->RRTrend_Series1->replace(myChart-
}
}
//RR_Poincare_Plot散点图将数据导入系列函数
void MainWindow::RR_Poincare_Plot()
{
myChart->RRPoincarePlot_Series1->clear();
myChart->RRPoincarePlot_Series1->setUseOpenGL(
for(uint i=0;i<5000/*myFile->RR_intervalLength
myChart->RRPoincarePlot_Series1->append(*(
}
//Differences_RR_Poincare_Plot差值散点图
void MainWindow::Differences_RR_Poincare_Plot()
{
myChart->DifferencesRRPoincarePlot_Series1->cl
myChart->DifferencesRRPoincarePlot_Series1->se
for(uint i=0;i<5000/*myFile->RR_intervalLength
{
myChart->DifferencesRRPoincarePlot_Series1
append((*(myFile->p_RR_Interval+i)
(*(myFile->p_RR_Interval+i)
}
}
//RR_Histogram直方图
void MainWindow::RR_Histogram()
{
//用桶排序提取RR间期直方图中该RR间期出现的次数
for(uint i=0;iRR_intervalLength;i++)
{
if((int)(*(myFile->p_RR_Interval+i))>2999)
continue;
RR_Histogram_RRNumber[(int)(*(myFile->p_RR
}
for(uint i=0;iRRHistogram_X_MaxSize;
myChart->RRHistogram_bar->append(RR_Histog
}
//DifferencesRR_Histogram差值直方图
void MainWindow::Differences_RR_Histogram()
{
//用桶排序提取RR间期直方图中该RR间期差值出现的次数
for(uint i=1;iRR_intervalLength;i++)
DifferencesRR_Histogram_RRNumber[(int)(*(m
for(uint i=0;iDifferencesRRHistogram
myChart->DifferencesRRHistogram_bar->appen
}
//DC心率减速力图
void MainWindow::DC()
{
for(int i=0;i<31;i++)
{
myChart->DC_Series1->append(QPointF(i-15,D
}
}
//AC心率加速力图
void MainWindow::AC()
{
for(int i=0;i<31;i++)
{
myChart->AC_Series1->append(QPointF(i-15,D
}
}
//ECG最大化窗口按钮
void MainWindow::on_ECG_MaxButton_toggled(bool che
{
if(checked)
{
ui->widget->hide();
ui->widget_2->hide();
ui->ECG_MaxButton->setWhatsThis(QString::f
}
else
{
ui->widget->show();
ui->widget_2->show();
ui->ECG_MaxButton->setWhatsThis(QString::f
}
}
void MainWindow::on_actionDCM_toggled(bool arg1)
{
if(arg1)
{
ui->widget->hide();
ui->widget_2->hide();
ui->ECG_MaxButton->setWhatsThis(QString::f
}
else
{
ui->widget->show();
ui->widget_2->show();
ui->ECG_MaxButton->setWhatsThis(QString::f
}
}
//treeView双击打开文件槽函数
void MainWindow::on_treeView_doubleClicked(const Q
{
InitHRVpNNandTD();
QString item;
char sign=0;
QString FilePath;
item=index.data().toString();
sign='h';
FilePath=myDataBase->SelectFilePath(item,&sign
myFile->HEAtoString(FilePath.toStdString().c_s
sign='d';
OpenDat();
FilePath=myDataBase->SelectFilePath(item,&sign
//调用DAT函数,生成心电数据
myFile->DATtoSignalAmplitude(FilePath.toStdStr
//生成提示信息
ListWidgetShow();
sign='a';
OpenAtr();
FilePath=myDataBase->SelectFilePath(item,&sign
//调用ATR函数,生成RR间期数据
myFile->ATRtoRRInterval(FilePath.toStdString()
ListWidgetShow();
OpenHea();
}
//listWidget程序运行说明信息显示函数
void MainWindow::ListWidgetShow()
{
//ui->listWidget->clear();
for(int i=0;iOpenFileList.length();i+
{
ui->listWidget->addItem(myFile->OpenFileLi
ui->listWidget->scrollToBottom();
}
ui->listWidget->addItem(QString("*************
"*************
"*************
"*************
}
//双击打开hea文件函数
void MainWindow::OpenHea()
{
QStringList PatientInformationList;
PatientInformationList.append(
QString::fromLocal8Bit("文件编号:")+QString("%1")
QString::fromLocal8Bit("信号个数:")+QString("%1").
QString::fromLocal8Bit("采样频率:")+QString("%1")
QString::fromLocal8Bit("采样时间:")+myFile->hea->
PatientInformationList.append(
QString::fromLocal8Bit("压缩格式:")+myFile->hea->
QString::fromLocal8Bit("信号长度:")+QString("%1")
QString::fromLocal8Bit("信号1采样方式:")+myFile->he
QString::fromLocal8Bit("信号2采样方式:")+myFile->he
PatientInformationList.append( QString::fromLo
ui->listWidget->addItems(PatientInformationLis
ui->listWidget->addItem(QString("*************
"*************
"*************
"*************
ui->listWidget->scrollToBottom();
}
//双击打开dat文件函数
void MainWindow::OpenDat()
{
this->on_ECG_StartButton_toggled(false);//关闭定时
if(myFile->p_sigal_amplitude_value1)//释放上一个dat
free(myFile->p_sigal_amplitude_value1);
if(myFile->p_sigal_amplitude_value2)
free(myFile->p_sigal_amplitude_value2);
myFile->OpenFileList.clear();//清空提示信息
ECG_nSkip=0;//设置跳转从头开始
myChart->ECG_Series1->clear();//清空图表
//myChart->ECG_ptrNew.clear();//清空图表
ui->ECG_StartButton->setEnabled(true);
ui->ECG_Painting_comboBox->setEnabled(true);
ui->ECG_WalkSpeed_spinBox->setEnabled(true);
}
//双击打开atr文件函数
void MainWindow::OpenAtr()
{
//HRV与RR界面
this->on_RRTrend_StartButton_toggled(false);//
if(myFile->p_RR_Interval)//清空上一个atr文件申请的内存空间
free(myFile->p_RR_Interval);
myFile->R_Wave.clear();
myFile->OpenFileList.clear();//清空提示信息
RR_Trend_nSkip=0;//设置从头开始跳转
myChart->RRTrend_ptrNew.clear();//清空图表
myChart->RRTrend_Series1->clear();//清空图表
myChart->RRPoincarePlot_Series1->clear();
myChart->DifferencesRRPoincarePlot_Series1->cl
myChart->AC_Series1->clear();
myChart->DC_Series1->clear();
ui->RRTrend_StartButton->setEnabled(true);
ui->HRV_AnalyzeButton->setEnabled(true);
ui->DC_AC_Analyze_button->setEnabled(true);
ui->HRV_Painting_comboBox->setEnabled(true);
ui->HRV_WalkSpeed_spinBox->setEnabled(true);
}
//设置显示模式的函数
void MainWindow::SetShowModel(int value)
{
switch (value) {
case 0:
disconnect(&myChart->ECG_Timer,&QTimer::ti
connect(&myChart->ECG_Timer,&QTimer::timeo
break;
case 1:
disconnect(&myChart->ECG_Timer,&QTimer::ti
connect(&myChart->ECG_Timer,&QTimer::timeo
break;
case 2:
myChart->ECG_Timer.stop();
disconnect(&myChart->ECG_Timer,&QTimer::ti
disconnect(&myChart->ECG_Timer,&QTimer::ti
break;
default:
break;
}
}
//设置字体的函数
QFont MainWindow::SetFontAndSize(QFont f, float si
{
f.setPointSizeF(size);
return f;
}
//设置主题风格按钮
void MainWindow::on_ECG_Background_comboBox_curren
{
myChart->ECG_Chart->setTheme(QChart::ChartThem
myChart->ECG_Series1->setColor(Qt::GlobalColor
myChart->ECG_axisX->setMinorGridLinePen(QPen(Q
myChart->ECG_axisY->setMinorGridLinePen(QPen(Q
}
//设置ECG网格线的颜色
void MainWindow::on_ECG_GridLines_comboBox_current
{
myChart->ECG_axisX->setGridLineColor(Qt::Globa
myChart->ECG_axisY->setGridLineColor(Qt::Globa
}
//ECG心电图扫描模式选择框按钮
void MainWindow::on_ECG_Painting_comboBox_currentI
{
SetShowModel(index);
}
//设置曲线颜色的按钮
void MainWindow::on_ECG_PenColor_comboBox_currentI
{
myChart->ECG_Series1->setColor(Qt::GlobalColor
}
//设置ECG曲线的线宽的按钮
void MainWindow::on_ECG_PenWidth_spinBox_valueChan
{
QPen myPen;
myPen.setWidth(arg1);
int value=ui->ECG_PenColor_comboBox->currentIn
myChart->ECG_Series1->setPen(myPen);
myChart->ECG_Series1->setColor(Qt::GlobalColor
}
//设置ECG图像走速按钮
void MainWindow::on_ECG_WalkSpeed_spinBox_valueCha
{
myChart->ECG_Timer.setInterval(arg1);
}
//设置ECG图表的标题的字体按钮
void MainWindow::on_ECG_Tiltle_fontComboBox_curren
{
myChart->ECG_Chart->setTitleFont(f);
}
//设置ECG图表的标题的颜色按钮
void MainWindow::on_ECG_TitleColor_pushButton_clic
{
QColor color=QColorDialog::getColor(Qt::red,th
QBrush myBrush;
myBrush.setColor(color);
myChart->ECG_Chart->setTitleBrush(myBrush);
}
//设置ECG图表中X轴的标题,注释的字体按钮
void MainWindow::on_ECG_Xlabel_fontComboBox_curren
{
myChart->ECG_axisX->setLabelsFont(f);
//f为用户选择的字体,第二个参数为当前界面Xlabel的大小值,不设置的话更改字体会变成默
myChart->ECG_axisX->setTitleFont(SetFontAndSiz
}
//设置ECG表中的Y轴标题,注释的字体按钮
void MainWindow::on_ECG_Ylabel_fontComboBox_curren
{
myChart->ECG_axisY->setLabelsFont(f);
myChart->ECG_axisY->setTitleFont(f);
}
//设置ECG图表中X轴标题,注释的颜色按钮
void MainWindow::on_ECG_XlabelColor_pushButton_cli
{
QColor color=QColorDialog::getColor(Qt::red,th
QBrush myBrush;
myBrush.setColor(color);
myChart->ECG_axisX->setTitleBrush(color);
myChart->ECG_axisX->setLabelsColor(color);
}
//设置ECG图表中Y轴标题,注释的颜色按钮
void MainWindow::on_ECG_Ylabel_pushButton_clicked(
{
QColor color=QColorDialog::getColor(Qt::red,th
QBrush myBrush;
myBrush.setColor(color);
myChart->ECG_axisY->setTitleBrush(color);
myChart->ECG_axisY->setLabelsColor(color);
}
//设置ECG图表中的X标题按钮
void MainWindow::on_ECG_Xlabel_lineEdit_returnPres
{
myChart->ECG_axisX->setTitleText(ui->ECG_Xlabe
}
//设置ECG图表中的X轴上y方向的方格线隐藏按钮
void MainWindow::on_ECG_XGridLineVisible_button_to
{
if(checked)
{
myChart->ECG_axisX->setGridLineVisible(tru
myChart->ECG_axisX->setMinorGridLineVisibl
}
else
{
myChart->ECG_axisX->setGridLineVisible(fal
myChart->ECG_axisX->setMinorGridLineVisibl
}
}
//设置ECG图表中X轴标题的大小
void MainWindow::on_ECG_XLabelFontSize_comboBox_cu
{
QFont myFont;
myFont.setPointSizeF(arg1.toFloat());
myChart->ECG_axisX->setTitleFont(myFont);
}
//设置ECG图表中的Y标题按钮
void MainWindow::on_ECG_Ylabel_lineEdit_returnPres
{
myChart->ECG_axisY->setTitleText(ui->ECG_Ylabe
}
//设置ECG图表中的Y轴上x方向的方格线隐藏按钮
void MainWindow::on_ECG_YGridLineVisible_button_to
{
if(checked)
{
myChart->ECG_axisY->setGridLineVisible(tru
myChart->ECG_axisY->setMinorGridLineVisibl
}
else
{
myChart->ECG_axisY->setGridLineVisible(fal
myChart->ECG_axisY->setMinorGridLineVisibl
}
}
//设置ECG图表中Y轴标题的大小
void MainWindow::on_ECG_YLabelFontSize_comboBox_cu
{
QFont myFont;
myFont.setPointSizeF(arg1.toFloat());
myChart->ECG_axisY->setTitleFont(myFont);
}
void MainWindow::InitHRVpNNandTD()
{
ui->HRV_SDNN->setText(QString::number(0,4,1));
ui->HRV_RMSSD->setText(QString::number(0,4,1))
ui->HRV_SDSD->setText(QString::number(0,4,1));
ui->HRV_pNN10->setText(QString::number(0,4,1))
ui->HRV_pNN20->setText(QString::number(0,4,1))
ui->HRV_pNN30->setText(QString::number(0,4,1))
ui->HRV_pNN40->setText(QString::number(0,4,1))
ui->HRV_pNN50->setText(QString::number(0,4,1))
ui->HRV_pNN60->setText(QString::number(0,4,1))
ui->HRV_pNN70->setText(QString::number(0,4,1))
ui->RR_SDNN->setText(QString::number(0,4,1));
ui->RR_RMSSD->setText(QString::number(0,4,1));
ui->RR_SDSD->setText(QString::number(0,4,1));
ui->RR_pNN10->setText(QString::number(0,4,1));
ui->RR_pNN20->setText(QString::number(0,4,1));
ui->RR_pNN30->setText(QString::number(0,4,1));
ui->RR_pNN40->setText(QString::number(0,4,1));
ui->RR_pNN50->setText(QString::number(0,4,1));
ui->RR_pNN60->setText(QString::number(0,4,1));
ui->RR_pNN70->setText(QString::number(0,4,1));
}
//设置HRV和RR界面中PNN和T/D的值
void MainWindow::SetHRVpNNandTD()
{
ui->HRV_SDNN->setText(QString::number(myHRVAna
ui->HRV_RMSSD->setText(QString::number(myHRVAn
ui->HRV_SDSD->setText(QString::number(myHRVAna
ui->HRV_pNN10->setText(QString::number(myHRVAn
ui->HRV_pNN20->setText(QString::number(myHRVAn
ui->HRV_pNN30->setText(QString::number(myHRVAn
ui->HRV_pNN40->setText(QString::number(myHRVAn
ui->HRV_pNN50->setText(QString::number(myHRVAn
ui->HRV_pNN60->setText(QString::number(myHRVAn
ui->HRV_pNN70->setText(QString::number(myHRVAn
ui->RR_SDNN->setText(QString::number(myHRVAnal
ui->RR_RMSSD->setText(QString::number(myHRVAna
ui->RR_SDSD->setText(QString::number(myHRVAnal
ui->RR_pNN10->setText(QString::number(myHRVAna
ui->RR_pNN20->setText(QString::number(myHRVAna
ui->RR_pNN30->setText(QString::number(myHRVAna
ui->RR_pNN40->setText(QString::number(myHRVAna
ui->RR_pNN50->setText(QString::number(myHRVAna
ui->RR_pNN60->setText(QString::number(myHRVAna
ui->RR_pNN70->setText(QString::number(myHRVAna
}
//设置DC、AC界面的指标参数
void MainWindow::SetDcAcParameter()
{
ui->DC_1->setText(QString::number(myFile->RREl
ui->AC_X_2->setText(QString::number(DCData->DC
ui->AC_X_1->setText(QString::number(DCData->DC
ui->AC_X->setText(QString::number(DCData->DC_A
ui->AC_X1->setText(QString::number(DCData->DC_
ui->DC_X_2->setText(QString::number(DCData->AC
ui->DC_X_1->setText(QString::number(DCData->AC
ui->DC_X->setText(QString::number(DCData->AC_A
ui->DC_X1->setText(QString::number(DCData->AC_
QPalette TextColor;
if(DCData->DC<=2.5)
{
TextColor.setColor(QPalette::WindowText,Qt
ui->DC_Text->setText(QString::fromLocal8Bi
}
else if(DCData->DC<=4.5)
{
TextColor.setColor(QPalette::WindowText,Qt
ui->DC_Text->setText(QString::fromLocal8Bi
}
else{
TextColor.setColor(QPalette::WindowText,Qt
ui->DC_Text->setText(QString::fromLocal8Bi
}
ui->DC_Value->setPalette(TextColor);
if(DCData->AC>=-2.5)
{
TextColor.setColor(QPalette::WindowText,Qt
ui->AC_Text->setText(QString::fromLocal8Bi
}
else if(DCData->AC>=-4.5)
{
TextColor.setColor(QPalette::WindowText,Qt
ui->AC_Text->setText(QString::fromLocal8Bi
}
else{
TextColor.setColor(QPalette::WindowText,Qt
ui->AC_Text->setText(QString::fromLocal8Bi
}
ui->AC_Value->setPalette(TextColor);
ui->DC_Value->setText(QString::number(DCData->
ui->AC_Value->setText(QString::number(DCData->
}
void MainWindow::on_HRV_AnalyzeButton_clicked()
{
ui->HRV_AnalyzeButton->setEnabled(false);
myHRVAnalyze=new HRVAnalyze(myFile->p_RR_Inter
SetHRVpNNandTD();
RR_Poincare_Plot();
Differences_RR_Poincare_Plot();
RR_Histogram();
Differences_RR_Histogram();
}
void MainWindow::on_DC_AC_Analyze_button_clicked()
{
ui->DC_AC_Analyze_button->setEnabled(false);
DCData->DC_Data(myFile->p_RR_Interval,myFile->
DC();
AC();
SetDcAcParameter();
}
//设置HRV主题风格按钮
void MainWindow::on_HRV_Background_comboBox_curren
{
myChart->RRTrend_Chart->setTheme(QChart::Chart
myChart->RRTrend_Series1->setColor(Qt::GlobalC
}
//设置HRV网格线的颜色
void MainWindow::on_HRV_GridLines_comboBox_current
{
myChart->RRTrend_axisX->setGridLineColor(Qt::G
myChart->RRTrend_axisY->setGridLineColor(Qt::G
}
//设置HRV曲线颜色的按钮
void MainWindow::on_HRV_PenColor_comboBox_currentI
{
myChart->RRTrend_Series1->setColor(Qt::GlobalC
}
//设置HRV曲线的线宽的按钮
void MainWindow::on_HRV_PenWidth_spinBox_valueChan
{
QPen myPen;
myPen.setWidth(arg1);
int value=ui->HRV_PenColor_comboBox->currentIn
myChart->RRTrend_Series1->setPen(myPen);
myChart->RRTrend_Series1->setColor(Qt::GlobalC
}
//设置HRV图像走速按钮
void MainWindow::on_HRV_WalkSpeed_spinBox_valueCha
{
myChart->RRTrend_Timer.setInterval(arg1);
}
//设置HRV图表中的X标题按钮
void MainWindow::on_HRV_XLabel_lineEdit_returnPres
{
myChart->RRTrend_axisX->setTitleText(ui->HRV_X
}
//设置HRV图表中X轴标题的大小
void MainWindow::on_HRV_XLabelFontSize_comboBox_cu
{
QFont myFont;
myFont.setPointSizeF(arg1.toFloat());
myChart->RRTrend_axisX->setTitleFont(myFont);
}
//设置HRV图表中的X轴上y方向的方格线隐藏按钮
void MainWindow::on_HRV_XGridLineVisible_Button_to
{
if(checked)
{
myChart->RRTrend_axisX->setGridLineVisible
myChart->RRTrend_axisX->setMinorGridLineVi
}
else
{
myChart->RRTrend_axisX->setGridLineVisible
myChart->RRTrend_axisX->setMinorGridLineVi
}
}
//设置HRV图表中的Y标题按钮
void MainWindow::on_HRV_Ylabel_lineEdit_returnPres
{
myChart->RRTrend_axisY->setTitleText(ui->HRV_Y
}
//设置HRV图表中Y轴标题的大小
void MainWindow::on_HRV_YLabelFontSize_comboBox_cu
{
QFont myFont;
myFont.setPointSizeF(arg1.toFloat());
myChart->RRTrend_axisY->setTitleFont(myFont);
}
//设置HRV图表中的Y轴上x方向的方格线隐藏按钮
void MainWindow::on_HRV_YGridLineVisible_Button_to
{
if(checked)
{
myChart->RRTrend_axisY->setGridLineVisible
myChart->RRTrend_axisY->setMinorGridLineVi
}
else
{
myChart->RRTrend_axisY->setGridLineVisible
myChart->RRTrend_axisY->setMinorGridLineVi
}
}
void MainWindow::on_actionECG_triggered(){ui->tabW
void MainWindow::on_actionRR_triggered(){ui->tabWi
void MainWindow::on_actionHRV_triggered(){ui->tabW
void MainWindow::on_actionDC_triggered(){ui->tabWi
void MainWindow::on_actionExit_triggered(){this->c
void MainWindow::on_actionOpen_triggered()
{
QString FilePath;
QString Path=myFile->fileDialog(this);
if(Path==NULL)return;
QString name=Path.mid(0,Path.length()-4);
myFile->HEAtoString(Path.toStdString().c_str()
OpenDat();
FilePath=name+".dat";
//调用DAT函数,生成心电数据
myFile->DATtoSignalAmplitude(FilePath.toStdStr
if(myFile->p_sigal_amplitude_value1==NULL)
{
QMessageBox::critical(this,QString::fromLo
return;
}
//生成提示信息
ListWidgetShow();
OpenAtr();
FilePath=name+".atr";
//调用ATR函数,生成RR间期数据
myFile->ATRtoRRInterval(FilePath.toStdString()
if(myFile->p_RR_Interval==NULL)
{
QMessageBox::critical(this,QString::fromLo
return;
}
ListWidgetShow();
OpenHea();
}
void MainWindow::on_actionHA_triggered()
{
QMessageBox::information(this,QString::fromLoc
}
void MainWindow::on_actionHH_triggered()
{
QDialog* myDialog=new QDialog(this);
myDialog->setWindowTitle(QString::fromLocal8Bi
myDialog->setGeometry(350,185,350,185);
QLabel* myLabel=new QLabel(myDialog);
myLabel->setScaledContents(true);
QGridLayout* myLayout=new QGridLayout;
myLayout->addWidget(myLabel);
myDialog->setLayout(myLayout);
myLabel->setPixmap(QPixmap(QString::fromLocal8
myDialog->show();
}
void MainWindow::on_actionHD_triggered()
{
QDialog* myDialog=new QDialog(this);
myDialog->setWindowTitle(QString::fromLocal8Bi
myDialog->setGeometry(350,185,350,185);
QLabel* myLabel=new QLabel(myDialog);
myLabel->setScaledContents(true);
QGridLayout* myLayout=new QGridLayout;
myLayout->addWidget(myLabel);
myDialog->setLayout(myLayout);
QFont myFont;
myFont.setBold(true);
myFont.setPixelSize(20);
myLabel->setFont(myFont);
myLabel->setText(QString::fromLocal8Bit("当DC值小
myDialog->show();
}
附 录 1)数据库模块 (1)头文件 database.h #include #include #include #include #include #include #include class DataBase { public: DataBase(); //数据库初始化函数 void DataBaseInit(); //数据库查询函数 QString SelectFilePath(QString select,char* sign); public: //模型变量 QStandardItemModel* model; private: //条目变量 QStandardItem* item; }; #endif // DATABASE_H (2)类文件 database.cpp #include "database.h" DataBase::DataBase(){} /* 函数名:DataBaseInit() * 参 数:无 * 作 用:连接数据库,导入数据 * * */ void DataBase::DataBaseInit() { 建立数据库视图 //添加 SQlite 数据库 QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE"); //设置数据库 db.setDatabaseName("../EcgData.db"); //打开数据库 if(!db.open())//数据库打开失败 { QMessageBox::warning(this,QString::fromLocal8Bit("错误"),db.lastError().text()); return; } QSqlQuery query; bool sign1=query.exec("create table EcgData(" "FID int primary key not null," "FNAME char(100)," "FPATH char(500),"
"FHEA char(300)," "FDAT char(300)," "FATR char(300));"); bool sign2=query.exec("insert into EcgData values" "(1,'16265','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/16265/','16265.hea','16265.dat','16265.atr')," "(2,'16272','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/16272/','16272.hea','16272.dat','16272.atr')," "(3,'16273','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/16273/','16273.hea','16273.dat','16273.atr')," "(4,'16420','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/16420/','16420.hea','16420.dat','16420.atr')," "(5,'16483','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/16483/','16483.hea','16483.dat','16483.atr')," "(6,'100','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/100/','100.hea','100.dat','100.atr')," "(7,'101','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/101/','101.hea','101.dat','101.atr')," "(8,'102','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/102/','102.hea','102.dat','102.atr')," "(9,'103','E:/Qt5.11.1/ChengXu/MyProject/ECG-Data/103/','103.hea','103.dat','103.atr');"); bool sign3=query.exec("select * from EcgData"); //创建标准模型 model=new QStandardItemModel; item=new QStandardItem; item->setText("File"); model->setHorizontalHeaderItem(0,item); //获取模型的根项(Root Item),根项是不可见的 QStandardItem* parentItem=model->invisibleRootItem(); qDebug()<setText(query.value("FNAME").toString()); itemFname->setIcon(QIcon(":/Image/image/list.png")); itemFname->setToolTip("indexA"); //将创建的标准项作为根项的子项 parentItem->appendRow(itemFname); //将创建的标准项作为新的父项 parentItem=itemFname; itemFhea->setText(query.value("FHEA").toString()); itemFhea->setIcon(QIcon(":/Image/image/expert2.png")); itemFdat->setText(query.value("FDAT").toString()); itemFdat->setIcon(QIcon(":/Image/image/ECG.png")); itemFatr->setText(query.value("FATR").toString()); itemFatr->setIcon(QIcon(":/Image/image/atr.png")); itemFname->appendRow(itemFhea); itemFname->appendRow(itemFdat); itemFname->appendRow(itemFatr); //获取模型的根项 parentItem=model->invisibleRootItem(); } } /* 函数名:SelectFilePath(QString select,char* sign) * 参 数:QString select 为用户点击选择的文件名 * char* sign 文件名标记
* 作 用:查询用户选择的文件,返回文件地址 * */ QString DataBase::SelectFilePath(QString select,char* sign) { QString name=select.mid(0,select.length()-4); QSqlQuery query; if(*sign=='h') { query.exec(QString("select FPATH from EcgData where FNAME=%1").arg(name)); while(query.next()) return query.value("FPATH").toString()+name+".hea"; } else if(*sign=='d') { query.exec(QString("select FPATH from EcgData where FNAME=%1").arg(name)); while(query.next()) return query.value("FPATH").toString()+name+".dat"; } else if(*sign=='a') { query.exec(QString("select FPATH from EcgData where FNAME=%1").arg(name)); while(query.next()) return query.value("FPATH").toString()+name+".atr"; } else return NULL; return NULL; } 2)文件协议模块 (1)头文件函数 openfile.h #ifndef OPENFILE_H #define OPENFILE_H #include #include #include #include #include class OpenFile { public: struct HEA { HEA() {} int FileNumber=0;//文件编号 int SignalNumber=0;//信号个数 double SamplingFrquemcy=0;//采样频率 int SignalLength=0;//每一信号长度 QString SamplinTime=NULL;//采样时间 QString FileName1=NULL;//信号 1 技术规划范说明文件名 QString Format1=NULL;//压缩格式 double Gain1=0;//增益
int ADC1=0;//ADC 分辨率 int Baseline1=0;//基线 int FirstValue1=0;//第一采样点初值 int CheckNumber1=0;//校验数 int IO1=0;//输入输出 QString File1=0;//文件 1 QString FileName2=0;//信号 2 技术规划范说明文件名 QString Format2=0;//压缩格式 double Gain2=0;//增益 int ADC2=0;//ADC 分辨率 int Baseline2=0;//基线(ADC 零值) int FirstValue2=0;//第一采样点初值 int CheckNumber2=0;//校验数 int IO2=0;//输入输出 QString File2=NULL;//文件 2 QString Annotation1=NULL;//注释 }; HEA* hea; void Hea(int sign,QString str); //函数定义区 public: //构造函数 OpenFile(); //析构函数 ~OpenFile(); //读取 hea 文件,并将 hea 文件数据转换为采样信息和患者基本信息 void HEAtoString(const char* HeaFilePath);//参数为 hea 文件的路径 //读取 dat 文件,并将 dat 数据转换为幅值 void DATtoSignalAmplitude(const char* DatFilePath);//参数为 dat 文件的路径 //读取 atr 文件,并将 atr 数据转换为幅值 void ATRtoRRInterval(const char *AtrFilePath);//参数为 atr 文件的路径 //打开文件对话框,并返回文件名 QString fileDialog(QWidget* parent); //判断文件大小函数 int fileSize(FILE* filename); //打开文件并将文件读入 malloc 内存 bool OpenFileToMalloc(const char* FilePath); //变量定义区 public: //定义文件大小 uint file_Size; //定义每组数据大小 uint data_Size; //采样信号 1/2 幅值内存存储头指针 double* p_sigal_amplitude_value1; double* p_sigal_amplitude_value2; //定义 RR 间期数组,索引值为第几个波峰,存储数值为距离上一个波峰的时间 ms double* p_RR_Interval=NULL; QVectorR_Wave; //定义 RR 间期数组的长度 uint RR_intervalLength=0; //输出信息
QStringList OpenFileList; //RR 剔除率 double RREliminatingRate=0.0; private: //定义文件指针 FILE* pFile; //定义读取数据是否成功的标志位 int fileReadIsSucceed; //定义 pFile 文件在 malloc 动态内存中分配空间的首地址 char* file_malloc_address; }; #endif // OPENFILE_H (2)将文件导入内存函数: /*函数名:OpenFileToMalloc *参 数:char* FilePath 为文件的路径 *作 用:打开文件并将文件读入 malloc 内存 * * * */ bool OpenFile::OpenFileToMalloc(const char* FilePath) { 为 file_Size 赋值,即文件大小可以使用 为 file_malloc_address 赋值,即文件已经读入内存 //1.打开文件 pFile = fopen(FilePath, "r"); if (!pFile) { OpenFileList<
} else{ OpenFileList<
str+=(*(file_malloc_address+i)); } for(i;iAnnotation1=str;//注释 free(file_malloc_address); } void OpenFile::Hea(int sign,QString str) { switch (sign) { case 0: hea->FileNumber=str.toInt();//文件编号 break; case 1: hea->SignalNumber=str.toInt();//信号个数 break; case 2: hea->SamplingFrquemcy=str.toDouble();//采样频率 break; case 3: hea->SignalLength=str.toInt();//每一信号长度 break; case 4: hea->SamplinTime=str;//采样时间 //qDebug()<<"4"<SamplinTime; break; case 5: hea->FileName1=str;//信号 1 技术规划范说明文件名 break; case 6: hea->Format1=str;//压缩格式 break; case 7: hea->Gain1=str.toDouble();//增益 break; case 8: hea->ADC1=str.toInt();//ADC 分辨率 break; case 9: hea->Baseline1=str.toInt();//基线 break; case 10: hea->FirstValue1=str.toInt();//第一采样点初值 break; case 11: hea->CheckNumber1=str.toInt();//校验数 break; case 12: hea->IO1=str.toInt();//输入输出 break; case 13:
hea->File1=str;//文件 1 break; case 14: hea->FileName2=str;//信号 2 技术规划范说明文件名 break; case 15: hea->Format2=str;//压缩格式 break; case 16: hea->Gain2=str.toDouble();//增益 break; case 17: hea->ADC2=str.toInt();//ADC 分辨率 break; case 18: hea->Baseline2=str.toInt();//基线(ADC 零值) break; case 19: hea->FirstValue2=str.toInt();//第一采样点初值 break; case 20: hea->CheckNumber2=str.toInt();//校验数 break; case 21: hea->IO2=str.toInt();//输入输出 break; case 22: hea->File2=str;//文件 2 break; default: break; } } (4)读取 dat 文件函数: /* 函数名:DATtoSignalAmplitude * 参 数:char *DatFilePath 为 dat 心电文件地址 * 作 用:调用 OpenFileToMalloc()函数导入文件,将 dat 数据转化为幅值, * * * */ void OpenFile::DATtoSignalAmplitude(const char *DatFilePath) { 数据 1 的内存头指针为 p_sigal_amplitude_value1,类型为 double 长度为 data_Size 数据 2 的内存头指针为 p_sigal_amplitude_value2,类型为 double 长度为 data_Size //1.打开文件,读入内存 OpenFileToMalloc(DatFilePath); if(!OpenFileToMalloc(DatFilePath))//如果读取文件失败,立即结束函数 return; data_Size = file_Size / 3;//计算每组数据的长度 //2.申请信号 1,信号 2 所需内存空间 p_sigal_amplitude_value1 = (double*)malloc(sizeof(double)*data_Size);//采样信号 1 幅值内存存储头指针 if (!p_sigal_amplitude_value1) { OpenFileList<
分享到:
收藏