第三代软件开发-QCustcomPlot波形标注
文章目录
- 第三代软件开发-QCustcomPlot波形标注
- 项目介绍
- QCustcomPlot波形标注
- 效果
- 初始化
- 绘制
关键字:
Qt
、
Qml
、
关键字3
、
关键字4
、
关键字5
项目介绍
欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。
在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。
在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。
无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!
QCustcomPlot波形标注
效果
先看看效果,如果抓取到波形,就会在对应的曲线上标注出起点,最高点和最低点,如下图所示。
嘿嘿嘿,不管你是之前就看过,还是从上一篇中了解到了第一个波形的检测方法,在哪里面你应该看到部分QCustcomPlot波形标注的内容,今天咱们这个其实原理还是那个原理,试试今天的这个标注的有点多了。
初始化
下面的代码没有啥技术含量就是把我们需要用到的控件全部都给它初始化了,完了再隐藏了,这样在默认没有抓到波形的情况下,就是没有的,对于用户来说是不知道我们做了啥操作的。
/**
* @brief XXXX::initWavesCatched 初始化幅值
*/
void XXXX::initWavesCatched()
{
/// 数据推平抓取到波形信号
if(m_dataChannel == 1)
{
connect(m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData,&Turing_ElectroPhysiologyPullData::signal_wavesCatched,
this,&XXXX::slot_wavesCatched);
}
else if(m_dataChannel == 2)
{
connect(m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData,&Turing_ElectroPhysiologyPullData::signal_wavesCatched,
this,&XXXX::slot_wavesCatched);
}
QPen pen;
pen.setColor("#2DAAE1");
pen.setWidth(2);
pen.setStyle(Qt::SolidLine);
m_labelTime = new QCPItemText(m_qCustomPlot);
m_labelTime->setLayer("overlay");
m_labelTime->setClipToAxisRect(false);
m_labelTime->setPadding(QMargins(5, 5, 5, 5));
m_labelTime->setFont(QFont("宋体", 16));
m_labelTime->setColor(QColor("#2DAAE1"));
m_labelTime->setVisible(false);
m_lineTime = new QCPItemLine(m_qCustomPlot);
m_lineTime->setPen(pen);
m_lineTime->setLayer("overlay");
m_lineTime->setClipToAxisRect(false);
m_lineTime->setVisible(false);
m_lineStart = new QCPItemLine(m_qCustomPlot);
m_lineStart->setPen(pen);
m_lineStart->setLayer("overlay");
m_lineStart->setClipToAxisRect(false);
m_lineStart->setVisible(false);
m_lineMax = new QCPItemLine(m_qCustomPlot);
m_lineMax->setPen(pen);
m_lineMax->setLayer("overlay");
m_lineMax->setClipToAxisRect(false);
m_lineMax->setVisible(false);
m_lineMin = new QCPItemLine(m_qCustomPlot);
m_lineMin->setPen(pen);
m_lineMin->setLayer("overlay");
m_lineMin->setClipToAxisRect(false);
m_lineMin->setVisible(false);
m_labelAmplitude = new QCPItemText(m_qCustomPlot);
m_labelAmplitude->setLayer("overlay");
m_labelAmplitude->setClipToAxisRect(false);
m_labelAmplitude->setPadding(QMargins(5, 5, 5, 5));
m_labelAmplitude->setFont(QFont("宋体", 16));
m_labelAmplitude->setColor(QColor("#2DAAE1"));
m_labelAmplitude->setVisible(false);
m_lineAmplitudeTop = new QCPItemLine(m_qCustomPlot);
m_lineAmplitudeTop->setPen(pen);
m_lineAmplitudeTop->setLayer("overlay");
m_lineAmplitudeTop->setClipToAxisRect(false);
m_lineAmplitudeTop->setVisible(false);
m_lineAmplitudeBottom = new QCPItemLine(m_qCustomPlot);
m_lineAmplitudeBottom->setPen(pen);
m_lineAmplitudeBottom->setLayer("overlay");
m_lineAmplitudeBottom->setClipToAxisRect(false);
m_lineAmplitudeBottom->setVisible(false);
}
绘制
经过上面的初始化,这里我们使用了Qt 的经典之一,信号槽,还记得上篇中组后,如果我们抓到波形就会触发一个信号,那个信号连接的槽就是这个函数,这个函数的作用就是根据上篇中的波形坐标,把对应的线,箭头,数据绘制在上面
/**
* @brief XXXX::slot_wavesCatched 算法波形画图
* @param chanelIndex
* @param startIndex
* @param crestIndex
* @param troughIndex
* @param endIndex
*/
void XXXX::slot_wavesCatched(int chanelIndex, int startIndex, int crestIndex, int troughIndex, int endIndex)
{
// qDebug() << "slot_wavesCatched 1 " << chanelIndex;
if(startIndex == crestIndex)
{
closeWavesCatched();
return;
}
if(chanelIndex +1 != m_dataChannel)
return;
// 分别计算 x、y 单位像素大小
// 获取 x 轴对象
// 获取 x 轴范围
// 获取绘图区域大小
// 计算单位像素大小
m_xPixelSize = m_qCustomPlot->xAxis->range().size() / m_qCustomPlot->viewport().width();
m_yPixelSize = m_qCustomPlot->yAxis->range().size() / m_qCustomPlot->viewport().height();
m_yStartValue= m_qCustomPlot->graph(0)->data()->at(startIndex)->value;
m_yCrestValue= m_qCustomPlot->graph(0)->data()->at(crestIndex)->value;
m_yTroughValue= m_qCustomPlot->graph(0)->data()->at(troughIndex)->value;
// double yEndValue= m_qCustomPlot->graph(chanelIndex)->data()->at(endIndex)->value;
// qDebug() << "m_yCrestValue" << m_yCrestValue << "m_yTroughValue" << m_yTroughValue;
m_yCrestValue= m_qCustomPlot->graph(0)->data()->at(crestIndex)->value;
m_yTroughValue= m_qCustomPlot->graph(0)->data()->at(troughIndex)->value;
m_lineStart->setVisible(true);
m_lineStart->start->setCoords(startIndex,m_yStartValue);
m_lineStart->end->setCoords(startIndex,m_yStartValue-100*m_yPixelSize);
if(startIndex-100*m_xPixelSize > 0)
{
m_labelTime->setVisible(true);
setStimDelay((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125);
m_labelTime->setText(QString::number((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125, 'f', 1) + "ms");
m_labelTime->position->setCoords(startIndex-100*m_xPixelSize, m_yStartValue-50*m_yPixelSize);
m_lineTime->setVisible(true);
m_lineTime->start->setParentAnchor(m_labelTime->right);
m_lineTime->end->setCoords(startIndex-1,m_yStartValue-50*m_yPixelSize);
m_lineTime->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)
}
else
{
m_labelTime->setVisible(true);
setStimDelay((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125);
m_labelTime->setText(QString::number((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125,'f',1) + "ms");
m_labelTime->position->setCoords(startIndex+50*m_xPixelSize, m_yStartValue-50*m_yPixelSize);
m_lineTime->setVisible(true);
m_lineTime->start->setParentAnchor(m_labelTime->left);
m_lineTime->end->setCoords(startIndex+1,m_yStartValue-50*m_yPixelSize);
m_lineTime->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)
}
if(crestIndex <troughIndex)
{
m_lineMax->setVisible(true);
m_lineMax->start->setCoords(crestIndex,m_yCrestValue);
m_lineMax->end->setCoords(endIndex,m_yCrestValue);
m_lineMin->setVisible(true);
m_lineMin->start->setCoords(crestIndex,m_yTroughValue);
m_lineMin->end->setCoords(endIndex,m_yTroughValue);
}
else
{
m_lineMax->setVisible(true);
m_lineMax->start->setCoords(troughIndex,m_yCrestValue);
m_lineMax->end->setCoords(endIndex,m_yCrestValue);
m_lineMin->setVisible(true);
m_lineMin->start->setCoords(troughIndex,m_yTroughValue);
m_lineMin->end->setCoords(endIndex,m_yTroughValue);
}
m_labelAmplitude->setVisible(true);
m_labelAmplitude->setText(QString("%1uV").arg(int(m_yCrestValue - m_yTroughValue)));
m_labelAmplitude->position->setCoords(troughIndex, (m_yCrestValue + m_yTroughValue)/2);
m_lineAmplitudeTop->setVisible(true);
m_lineAmplitudeTop->start->setParentAnchor(m_labelAmplitude->top);
m_lineAmplitudeTop->end->setCoords(troughIndex,m_yCrestValue-1);
m_lineAmplitudeTop->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)
m_lineAmplitudeBottom->setVisible(true);
m_lineAmplitudeBottom->start->setParentAnchor(m_labelAmplitude->bottom);
m_lineAmplitudeBottom->end->setCoords(troughIndex,m_yTroughValue+1);
m_lineAmplitudeBottom->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)
m_qCustomPlot->replot(QCustomPlot::rpQueuedReplot);
}