一、环境介绍
操作系统: win10 64位
QT版本: QT5.12.6
编译器: MinGW 32
二、功能介绍
软件端接收设备上传的心电数据、运动数据、体温数据进行处理、存储显示。
完整项目源码下载链接: https://download.csdn.net/download/xiaolong1126626497/18607424
三、核心代码
3.1 widget.cpp
代码语言:javascript复制#include "widget.h"
#include "ui_widget.h"
#define AppFontName "Microsoft YaHei"
#define AppFontSize 9
#define TextColor QColor(255,255,255)
#define Plot_NoColor QColor(0,0,0,0)
//曲线1的颜色
#define HeartRate_Plot_DotColor QColor(236,110,0)
#define HeartRate_Plot_LineColor QColor(246,98,0)
#define HeartRate_Plot_BGColor QColor(246,98,0,80)
//曲线2的颜色
#define HeartRate_Plot_DotColor_2 Qt::blue
#define HeartRate_Plot_LineColor_2 Qt::blue
#define HeartRate_Plot_BGColor_2 Qt::blue
#define TextWidth 1
#define LineWidth 2
#define DotWidth 5
//一个刻度里的小刻度数量--太小的话显示的时间会重叠
#define HeartRate_Plot_Count 5
//Y轴最大范围值
#define HeartRate_Plot_MaxY 3000
/*
* 设置QT界面的样式
*/
void Widget::SetStyle(const QString &qssFile) {
QFile file(qssFile);
if (file.open(QFile::ReadOnly)) {
QString qss = QLatin1String(file.readAll());
qApp->setStyleSheet(qss);
QString PaletteColor = qss.mid(20,7);
qApp->setPalette(QPalette(QColor(PaletteColor)));
file.close();
}
else
{
qApp->setStyleSheet("");
}
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
/*服务器线程*/
//开始信号
connect(this,SIGNAL(StartServerThread()),&tcp_server_class,SLOT(run()));
//日志信号
connect(&tcp_server_class,SIGNAL(LogSend(QString)),this,SLOT(Log_Display(QString)));
//移动到线程
tcp_server_class.moveToThread(&tcp_server_thread);
tcp_server_thread.start(); //启动线程
StartServerThread(); //创建服务器
this->setWindowTitle("健康监控管家");
//波形图界面初始化
InitForm();
InitPlot();
HeartRate_InitPlot();
HeartRate_LoadPlot();
SetStyle(":/blue.css");
//开始加载数据
plot_timer->start(100);
}
Widget::~Widget()
{
delete ui;
}
//日志显示
void Widget::Log_Display(QString text)
{
QPlainTextEdit *plainTextEdit_log=ui->plainTextEdit_log;
//设置光标到文本末尾
plainTextEdit_log->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
//当文本数量超出一定范围就清除
if(plainTextEdit_log->toPlainText().size()>1024*4)
{
plainTextEdit_log->clear();
}
plainTextEdit_log->insertPlainText(text);
//移动滚动条到底部
QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
if(scrollbar)
{
scrollbar->setSliderPosition(scrollbar->maximum());
}
}
//查看服务器状态
void Widget::on_toolButton_server_stat_clicked()
{
QString text="服务器IP地址列表:n";
QList<QHostAddress> list = QNetworkInterface::allAddresses();
for(int i=0;i<list.count();i )
{
QHostAddress addr=list.at(i);
if(addr.protocol() == QAbstractSocket::IPv4Protocol)
{
text =addr.toString() "n";
}
}
text ="服务器端口号:8888n";
if(ClientSocket)
{
if(ClientSocket->socketDescriptor()==-1)
{
text ="设备未连接n";
}
else
{
text ="设备连接成功n";
}
}
else
{
text ="设备未连接n";
}
QMessageBox::about(this,"状态信息",text);
}
//窗口关闭事件
void Widget::closeEvent(QCloseEvent *event)
{
tcp_server_thread.quit();
tcp_server_thread.wait();
}
void Widget::InitForm()
{
//初始化随机数种子
QTime time = QTime::currentTime();
qsrand(time.msec() time.second() * 1000);
//初始化动态曲线定时器
plot_timer = new QTimer(this);
connect(plot_timer, SIGNAL(timeout()), this, SLOT(HeartRate_LoadPlot()));
plots.append(ui->plot2);
}
void Widget::InitPlot()
{
//设置纵坐标名称
plots.at(0)->yAxis->setLabel("心电数据(单位:%)");
//设置纵坐标范围
plots.at(0)->yAxis->setRange(0, HeartRate_Plot_MaxY);
//设置支持鼠标移动缩放波形界面
plots.at(0)->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
//设置背景颜色
#if 1
foreach (QCustomPlot *plot, plots)
{
//设置字体大小
QFont font = QFont(AppFontName, AppFontSize - 2);
plot->legend->setFont(font);
plot->xAxis->setLabelFont(font);
plot->yAxis->setLabelFont(font);
plot->xAxis->setTickLabelFont(font);
plot->yAxis->setTickLabelFont(font);
//设置坐标颜色/坐标名称颜色
plot->yAxis->setLabelColor(TextColor);
plot->xAxis->setTickLabelColor(TextColor);
plot->yAxis->setTickLabelColor(TextColor);
plot->xAxis->setBasePen(QPen(TextColor, TextWidth));
plot->yAxis->setBasePen(QPen(TextColor, TextWidth));
plot->xAxis->setTickPen(QPen(TextColor, TextWidth));
plot->yAxis->setTickPen(QPen(TextColor, TextWidth));
plot->xAxis->setSubTickPen(QPen(TextColor, TextWidth));
plot->yAxis->setSubTickPen(QPen(TextColor, TextWidth));
//设置画布背景色
QLinearGradient plotGradient;
plotGradient.setStart(0, 0);
plotGradient.setFinalStop(0, 350);
plotGradient.setColorAt(0, QColor(80, 80, 80));
plotGradient.setColorAt(1, QColor(50, 50, 50));
plot->setBackground(plotGradient);
//设置坐标背景色
QLinearGradient axisRectGradient;
axisRectGradient.setStart(0, 0);
axisRectGradient.setFinalStop(0, 350);
axisRectGradient.setColorAt(0, QColor(80, 80, 80));
axisRectGradient.setColorAt(1, QColor(30, 30, 30));
plot->axisRect()->setBackground(axisRectGradient);
//设置图例提示位置及背景色
plot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop | Qt::AlignRight);
plot->legend->setBrush(QColor(255, 255, 255, 200));
plot->replot();
}
#endif
}
void Widget::HeartRate_InitPlot()
{
plots.at(0)->addGraph();
plots.at(0)->graph(0)->setName("心电数据1");
plots.at(0)->graph(0)->setPen(QPen(HeartRate_Plot_LineColor, LineWidth));
plots.at(0)->graph(0)->setScatterStyle(
QCPScatterStyle(QCPScatterStyle::ssCircle,
QPen(HeartRate_Plot_DotColor, LineWidth),
QBrush(HeartRate_Plot_DotColor), DotWidth));
//设置动态曲线的横坐标格式及范围
plots.at(0)->xAxis->setTickLabelType(QCPAxis::ltDateTime);
plots.at(0)->xAxis->setDateTimeFormat("HH:mm:ss");
plots.at(0)->xAxis->setAutoTickStep(true);
plots.at(0)->xAxis->setTickStep(0.5);
plots.at(0)->xAxis->setRange(0, HeartRate_Plot_Count, Qt::AlignRight);
plots.at(0)->addGraph();//相当于添加一条新的曲线
plots.at(0)->graph(1)->setName("心电数据2");
plots.at(0)->graph(1)->setPen(QPen(HeartRate_Plot_LineColor_2, LineWidth));
plots.at(0)->graph(1)->setScatterStyle(
QCPScatterStyle(QCPScatterStyle::ssCircle,
QPen(HeartRate_Plot_DotColor_2, LineWidth),
QBrush(HeartRate_Plot_DotColor_2), DotWidth));
//设置是否需要显示曲线的图例说明
foreach (QCustomPlot *plot, plots)
{
plot->legend->setVisible(true);
plot->replot();
}
//得到数据指针
mData_0 = plots.at(0)->graph(0)->data();
mData_1 = plots.at(0)->graph(1)->data();
}
void addToDataBuffer(QCPDataMap *mData,double x, double y)
{
QCPData newData;
newData.key = x;
newData.value = y;
mData->insert(x, newData);
}
//加载曲线数据
void Widget::HeartRate_LoadPlot()
{
int i;
bool flag=false;
for(i=0;i<5;i )
{
//得到秒单位的时间
HeartRate_plot_key = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0;
//心电数据1
HeartRate_plot_value=uart_queue_data.read_queueA();
if(HeartRate_plot_value>0)
{
flag=true;
addToDataBuffer(mData_0,HeartRate_plot_key,HeartRate_plot_value);
}
//心电数据2
HeartRate_plot_value=uart_queue_data.read_queueB();
if(HeartRate_plot_value>0)
{
flag=true;
addToDataBuffer(mData_1,HeartRate_plot_key,HeartRate_plot_value);
}
}
if(flag)
{
plots.at(0)->xAxis->setRange(HeartRate_plot_key, HeartRate_Plot_Count , Qt::AlignRight);
plots.at(0)->rescaleAxes(false); //设置图表完全可见
plots.at(0)->replot();
}
/*
A:心电数据1,B:新电数据2,C:运动步数,D:运动距离,E:体表温度
例如: "A:1633215,B:1833215,C:45,D:28,E:66.55"
*/
int val=uart_queue_data.read_queueC();
if(val>0)
{
ui->lcdNumber_bumber->display(val);
}
val=uart_queue_data.read_queueD();
if(val>0)
{
ui->lcdNumber_len->display(val);
}
double tmp_val=uart_queue_data.read_queueE();
if(tmp_val>0)
{
ui->lcdNumber_temp->display(tmp_val);
}
}
void Widget::on_toolButton_src_data_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
}
void Widget::on_toolButton_image_data_clicked()
{
ui->stackedWidget->setCurrentIndex(1);
}
void Widget::on_toolButton_clear_clicked()
{
mData_0->clear();
mData_1->clear();
}
3.2 widget.h
代码语言:javascript复制#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "server.h"
#include <QPlainTextEdit>
#include <QTextCursor>
#include <QScrollBar>
#include <QPalette>
#include "qcustomplot.h"
#include "smoothcurvecreator.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void SetStyle(const QString &qssFile);
QThread tcp_server_thread; //服务器工作线程
TCPServer tcp_server_class;
//绘制实时曲线
QTimer *plot_timer;
QList <QCustomPlot *> plots;
double HeartRate_plot_key;
unsigned int HeartRate_plot_value;
//曲线数据点缓冲区
QCPDataMap *mData_0;
QCPDataMap *mData_1;
signals:
void StartServerThread(); //启动服务器线程
private slots:
void Log_Display(QString text);
void on_toolButton_server_stat_clicked();
void HeartRate_InitPlot();
void HeartRate_LoadPlot();
void InitPlot();
void InitForm();
void on_toolButton_src_data_clicked();
void on_toolButton_image_data_clicked();
void on_toolButton_clear_clicked();
protected:
void closeEvent(QCloseEvent *event); //窗口关闭
private:
Ui::Widget *ui;
};
#endif // WIDGET_H