QT-qcustomplot应用示例

news2024/9/23 17:13:24

QT-qcustomplot应用示例

  • 前言
  • 一、演示效果
  • 二、关键程序
  • 三、资源链接


前言

提供曲线显示示例过程

一、演示效果

请添加图片描述

二、关键程序

// 生成曲线图
void QtWidgetsApplication1::setupQuadratic()
{
	if (m_strViewMachineIndexList.size() <= 0)
		return;

	// 进度条默认0
	ui.progressBar->setValue(0);

	// 算每个机器显示要多少值
	int nProgessItem = 100 / m_strViewMachineIndexList.size();
	int nProgessValue = 0;

	auto customPlot = ui.customPlot;
	double fMinX = 100, fMaxX = -1;
	double fMinY = 100, fMaxY = -1;

	int nGraphIndex = -1;
	
	m_strXValueList.removeOne("");
	int nIndexColor=0;

	// 初始化图像显示
	customPlot->clearGraphs();
	customPlot->clearItems();
	customPlot->clearPlottables();

	// 颜色控件不可见
	for (int i = 0; i < m_pLabelList.size(); i++)
	{
		m_pLabelList[i]->setVisible(false);
		m_pFrameList[i]->setVisible(false);
	}

	// 根据要显示多个图像,再设置显示多少个颜色控件
	for (int i = 0; i < m_strViewMachineIndexList.size(); i++)
	{
		if (i >= m_pFrameList.size() || i >= m_pLabelList.size())
		{
			continue;
		}

		m_pLabelList[i]->setVisible(true);
		m_pFrameList[i]->setVisible(true);
		m_pLabelList[i]->setText(QString(u8"图像[%1]").arg(m_strViewMachineIndexList[i].toInt()));
	}

	// 遍历所有的机器
	for (size_t iMachine = 0; iMachine < m_strXValueList.size(); iMachine++)
	{
		// 如果不是选择的机器内的就不处理
		if (!m_strViewMachineIndexList.contains(QString("%1").arg(iMachine+1)))
		{
			continue;
		}

		// 获取曲线要显示的颜色
		QColor color;
		if (nIndexColor < m_colorList.size())
			color = m_colorList[nIndexColor++];
		
		// 按“ 2 ”切分字符
		QString strLine = m_strXValueList[iMachine];
		QStringList str2List = strLine.split(" 2 ");

		qDebug() << QString(u8"X[%1]:%2").arg(iMachine).arg(strLine);
		QString strLogX;
		QString strLogY;


		// 用来计算虚线过渡的显示
		QStringList strXTranList;
		QStringList strYTranList;
		for (size_t i = 0; i < str2List.size(); i++)
		{
			int nNext = i + 1;
			if (nNext < str2List.size())
			{
				QString str0 = str2List[i].split(" ").takeLast();
				QString str1 = str2List[nNext].split(" ").takeFirst();

				strXTranList << str0 << str1;
			}
		}

		int nPenSize = 2;   // 画曲线画笔的大小
		double fAe = 0;
		double fPm = 0; 

		// 开始画
		for (size_t i2 = 0; i2 < str2List.size(); i2++)
		{
			if (i2 != 0)
				fPm++;

			double fFreeTime = 0;  // 空闲累计时间
			QStringList str1List = str2List[i2].split(" ");
			double dBeginValue = 0;
			double dAeTemp = 0;
			double dLastYValue = 0;   // 上一个Y值,主要是用来画空闲时间

			// 获取第一个首元素,X值需要做偏执
			dBeginValue = str2List[i2].split(" ").takeFirst().toDouble();

			str1List.removeOne("");
			for (int i1 = 0; i1 < str1List.size(); i1++)
			{
				bool bEnablFreeTime = false; // 判断当前是否再空闲时间区间内
				if (str1List[i1] == "1" && (i1-1)>=0 )
				{
					if (true)
					{
						// 画空闲直线
						int nCount = 2;
						QVector<double> x(nCount), y(nCount);
						x[0] = str1List[i1-1].toDouble();
						y[0] = dLastYValue;
						x[1] = str1List[i1 + 1].toDouble();
						y[1] = dLastYValue;

						nGraphIndex++;
						customPlot->addGraph();
						customPlot->graph(nGraphIndex)->setData(x, y);
						QPen pen;
						pen.setWidthF(nPenSize);
						pen.setColor(color);
						customPlot->graph(nGraphIndex)->setPen(pen);
					}

					// 遍历到1直接跳过
					continue;
				}
				int jNext = i1 + 1;
				if (jNext >= str1List.size())
				{
					// 越界
					break;
				}

				// 如果下个是1,继续获取
				if (str1List[jNext] == "1")
				{
					bEnablFreeTime = true;
					jNext += 1;
					if (jNext >= str1List.size())
					{
						break;
					}

				}

				double fX[2] = { 0 };
				double fY[2] = { 0 };

				// 更加X坐标获取Y轴
				fX[0] = str1List[i1].toDouble();
				fX[1] = str1List[jNext].toDouble();

				if (bEnablFreeTime)
				{
					fFreeTime = fFreeTime + (fX[1]-fX[0]);
					// 获取到空闲时间后返回
					continue;
				}
				fY[0] = getYValue(iMachine, fX[0] - dBeginValue - fFreeTime, fPm, fAe,true);
				fY[1] = getYValue(iMachine, fX[1] - dBeginValue - fFreeTime, fPm, fAe, true);

				dLastYValue = fY[1];

				strLogX = strLogX + QString("%1").arg(fX[0]) + " " + QString("%1").arg(fX[1]) + " ";
				strLogY = strLogY + QString("%1").arg(fY[0]) + " " + QString("%1").arg(fY[1]) + " ";

				if (strXTranList.contains(str1List[i1]))
					strYTranList << QString("%1").arg(fY[0]);

				if (strXTranList.contains(str1List[jNext]))
					strYTranList << QString("%1").arg(fY[1]);

				if (abs(fY[1] - fY[0]) < 0.01)
				{
					// 相等
					// 画直线
					int nCount = 2;
					QVector<double> x(nCount), y(nCount);
					x[0] = fX[0];
					y[0] = fY[0];
					x[1] = fX[1];
					y[1] = fY[1];

					nGraphIndex++;
					customPlot->addGraph();
					customPlot->graph(nGraphIndex)->setData(x, y);
					QPen pen;
					pen.setWidthF(nPenSize);
					pen.setColor(color);
					customPlot->graph(nGraphIndex)->setPen(pen);
				}
				else
				{
					// 画弧形
					int nCount = fX[1] - fX[0];

					// 做线段切分
					QVector<double> x(nCount), y(nCount);
					for (int i = 0; i < nCount; ++i)
					{
						x[i] = fX[0] + i;
						y[i] = getYValue(iMachine, x[i] - dBeginValue - fFreeTime, fPm, fAe);
					}

					nGraphIndex++;
					customPlot->addGraph();
					customPlot->graph(nGraphIndex)->setData(x, y);
					QPen pen;
					pen.setWidthF(nPenSize);
					pen.setColor(color);
					customPlot->graph(nGraphIndex)->setPen(pen);
				}

				// 累计机器的运行时间
				if (!bEnablFreeTime)
				{
					// 累计ae的值
					dAeTemp = dAeTemp + (fX[1] - fX[0]);
				}


				// 获取X,Y轴最大值和最小值
				for (int  j = 0; j < 2; j++)
				{
					if (fX[j] > fMaxX)
						fMaxX = fX[j];

					if (fX[j] < fMinX)
						fMinX = fX[j];

					if (fY[j] > fMaxY)
						fMaxY = fY[j];

					if (fY[j] < fMinY)
						fMinY = fY[j];
				}
			}

			fAe = dAeTemp;
		}

		// 画过度线
		if (strXTranList.size() == strYTranList.size()
			&& strXTranList.size() > 0)
		{
			for (size_t i = 0; i < strXTranList.size(); i+=2)
			{
				int iNext = i + 1;
				if (iNext < strXTranList.size())
				{
					// 画直线
					int nCount = 2;
					QVector<double> x(nCount), y(nCount);
					x[0] = strXTranList[i].toDouble();
					y[0] = strYTranList[i].toDouble();
					x[1] = strXTranList[iNext].toDouble();
					y[1] = strYTranList[i].toDouble();

					// 第一条虚线
					nGraphIndex++;
					customPlot->addGraph();
					customPlot->graph(nGraphIndex)->setData(x, y);
					QPen pen;
					pen.setWidthF(1);
					pen.setStyle(Qt::PenStyle::DashLine);
					pen.setColor(Qt::gray);
					customPlot->graph(nGraphIndex)->setPen(pen);

					// 第二条虚线
					x[0] = strXTranList[iNext].toDouble();
					y[0] = strYTranList[i].toDouble();
					x[1] = strXTranList[iNext].toDouble();
					y[1] = strYTranList[iNext].toDouble();
					nGraphIndex++;
					customPlot->addGraph();
					customPlot->graph(nGraphIndex)->setData(x, y);
					customPlot->graph(nGraphIndex)->setPen(pen);
					customPlot->graph(nGraphIndex)->setPen(pen);
				}
			}
		}

		nProgessValue += nProgessItem;
		ui.progressBar->setValue(nProgessValue);

		qDebug() << QString(u8"strLogX[%1]:%2").arg(iMachine).arg(strLogX);
		qDebug() << QString(u8"strLogY[%1]:%2").arg(iMachine).arg(strLogY) << "\n";


	}

	customPlot->xAxis->setLabel(u8"加工时间/t");
	customPlot->yAxis->setLabel(u8"健康评价函数值");

	customPlot->xAxis->setRange(fMinX, fMaxX);
	customPlot->yAxis->setRange(0, 1);
	customPlot->replot();
	ui.progressBar->setValue(100);

}

bool QtWidgetsApplication1::openFile(QString strPath)
{
	if (!strPath.isEmpty())
	{
		QFile file(strPath);
		if (file.open(QIODevice::ReadOnly | QIODevice::Text))
		{
			m_strXValueList.clear();
			QTextStream in(&file);
			while (!in.atEnd())
			{
				QString strLine = in.readLine();

				// 如果是“****”就不要
				if (strLine.indexOf("*") != -1)
					continue;

				if (!strLine.isEmpty())
					m_strXValueList << strLine;
			}

			file.close();
		}
	}

	if (m_strXValueList.size() == 0)
	{
		return false;
	}

	// 按照4组来
	int nSize = m_strXValueList.size() / 4;

	// 计算每组多少个机器
	int nCount = m_strXValueList.size() / nSize;

	// 看看有没除不尽的
	int nLeaveCount = m_strXValueList.size() % nSize;

	// 创建做多需要显示不同的颜色
	while (m_pHBoxLayoutList.size() < nSize)
	{
		// 创建水平布局
		auto pHbox = new QHBoxLayout(this);
		m_pHBoxLayoutList << pHbox;
		int nNum = m_pHBoxLayoutList.size();

		// 创建文本
		auto pLabel = new QLabel(QString("%1").arg(nNum), this);
		pLabel->setObjectName(QString("%1").arg(nNum));
		m_pLabelList << pLabel;

		// 生成随机颜色
		int r = rand() % 256;
		int g = rand() % 256;
		int b = rand() % 256;

		// 创建颜色显示
		auto pFrame = new QFrame(this);
		pFrame->setFixedSize(70, 30);
		pFrame->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(r).arg(g).arg(b));
		m_pFrameList << pFrame;
		m_colorList << QColor(qRgb(r, g, b));

		// 先进行水平布局
		pHbox->addWidget(pLabel);
		pHbox->addWidget(pFrame);
		pHbox->addStretch();

		// 将水平布局添加垂直布局
		m_pVBoxLayout->addLayout(pHbox);
		m_pVBoxLayout->addStretch();

	}


	// 显示单元项
	ui.listWidget->setStyleSheet("QListWidget::item { margin-bottom: 10px; }");
	ui.listWidget->clear();
	for (int i = 0; i < nCount; i++)
	{
		if (i == (nCount - 1) && nLeaveCount != 0)
			ui.listWidget->addItem(QString(u8"图像[%1~%2]").arg(i*nSize + 1).arg(i*nSize + nLeaveCount));
		else
			ui.listWidget->addItem(QString(u8"图像[%1~%2]").arg(i*nSize + 1).arg(i*nSize + nSize));
	}

	// 刷新X值列表显示
	updateTableWidget();

	// 设置默认显示
	int nDefalutIndex = 0;
	if (nDefalutIndex < ui.listWidget->count())
	{
		QListWidgetItem *item = ui.listWidget->item(nDefalutIndex);
		ui.listWidget->setCurrentItem(item);
	}

	// 先隐藏颜色控件不可见
	for (int i = 0; i < m_pLabelList.size(); i++)
	{
		m_pLabelList[i]->setVisible(false);
		m_pFrameList[i]->setVisible(false);
	}

	return true;
}

三、资源链接

https://download.csdn.net/download/u013083044/88027002

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

能源在线监测管理系统平台

能源在线监测管理系统平台是一种集能源数据采集、处理、分析、展示和管理于一体的综合性平台。该平台通过现代信息技术手段&#xff0c;对企业、机构或个人的能源消耗、能源质量、能源成本等方面进行实时监测和管理&#xff0c;为企业和政府部门的能源管理和决策提供有力支持。…

【语音处理】基于加权压力匹配方法(WPMM)的私人声音系统研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

lammps教程:ovito转换data文件格式的方法

我是小马老师&#xff0c;本文与你分享一些关于lammps data文件格式转换的技巧和经验。 lammps是一个高度可定制的分子动力学模拟软件&#xff0c;它提供了丰富的功能和灵活的输入文件格式。其中&#xff0c;data文件是lammps中最常用的输入文件之一&#xff0c;用于描述模拟系…

Epoll 到底是什么?“不” 简单的网络I/O模型?

1 简介 Epoll 是个很老的知识点&#xff0c;是后端工程师的经典必修课。这种知识具备的特点就是研究的人多&#xff0c;所以研究的趋势就会越来越深。当然分享的人也多&#xff0c;由于分享者水平参差不齐&#xff0c;也产生的大量错误理解。 今天我再次分享 epoll&#xff0…

USB转GSM模块发送中英文测试

目录 使用模块前注意事项模块测试发送英文短信发送中文短信手机收到短信页面常见问题 总结 使用模块前注意事项 使用USB转GSM模块要 注意 两点: 1.所在地要有2G基站,因为这是2G信号产品。 2.最好使用移动卡&#xff0c;有些地方电信和联通卡无法使用。 模块测试 这里介绍模块…

在安卓手机搭建kali环境,手机变成便携式渗透神器

简介 kali是著名的黑客专用系统&#xff0c;一般都是直接装在物理机或者虚拟机上&#xff0c;我们可以尝试把kali安装在手机上&#xff0c;把手机打造成一个便携式渗透神器。 我们需要下载以下3款软件&#xff1a; (1).Termux(终端模拟器) (2).AnLinux(里边有各种安装liunx…

GPT时代,寻找讯飞星火大模型的算力支点

作者 | 辰纹 来源 | 洞见新研社 大模型的“涌现”还在持续。 5月底举行的中关村论坛上&#xff0c;有专家披露&#xff0c;中国10亿级参数规模以上的大模型已经发布了79个&#xff0c;刚刚结束的世界人工智能大会上&#xff0c;又有一批大模型批量发布。 大模型的热度居高不…

华大HC32F460 TCP Server实验

目录 1.实验目标 2.实验准备 3.主流程图 4.驱动代码 5.实验步骤 1.实验目标 本实验使用W5500服务器功能&#xff0c;通过串口实现与本地客户端透传数据。 2.实验准备 硬件搭建&#xff1a;ZW-HC32F460-BZ标准版开发板1套 软件搭建&#xff1a;MDK5.22 3.主流程图 4.驱动…

css实现按钮圆角渐变样式

最终成果图&#xff1a; 背景&#xff1a; 最近项目数据大屏这个样式给我卡住了&#xff0c;起因是UI设计想要按钮边框渐圆角背景透明渐变&#xff0c;我查找了好多资料也在问答里提问&#xff0c;都没有实现初始样式。原因是如果想用渐变边框就会使用到属性border-image&#…

在Microsoft Excel中带单位的数字如何求和

使用 Excel 中的 SUM 函数对一系列单元格、整列或非连续单元格求和。要创建出色的 SUM 公式&#xff0c;请将 SUM 函数与其他 Excel 函数结合使用&#xff0c;然而 SUM 函数不能直接对带单位的数字进行求和。 当直接相加带单位的几个数字会出现如下错误&#xff1a; 错误的原因…

811. 交换数值

链接&#xff1a; https://www.acwing.com/problem/content/813/ 题目&#xff1a; 输入两个整数 xx 和 yy&#xff0c;请你编写一个函数, 交换两个整数的数值并输出交换后的 xx 和 yy。 C中的格式为&#xff1a;void swap(int &x, int &y)。 Java中的格式为&#xff1…

【软件测试】Git 将项目本地推送至GitHub与Gitee(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Gitee拉取Github仓…

KeyShot 2023 Pro 对 Mac 和 Windows 系统的要求

KeyShot 2023 Pro 是一款功能强大的计算机辅助设计&#xff08;CAD&#xff09;渲染软件&#xff0c;它为用户提供了高质量的视觉效果和逼真渲染。 KeyShot 2023 Pro for Mac可以与各种主流 CAD 软件进行集成&#xff0c;包括 SolidWorks、AutoCAD、Rhinoceros、Fusion 360 等…

simulink matlab function

目录 改形参类型​编辑 多输出值 排序 peisistent 关键字&#xff0c;静态相当于static function添加trigger 输出调用function call() 改形参类型 多输出值 function [y1,y2] myfcn(u1,u2)y1 u1u2; y2 u1-u2; 排序 peisistent 关键字&#xff0c;静态相当于static func…

MIT 6.S081 -- Virtual memory for applications

MIT 6.S081 -- Virtual memory for applications 引言应用程序使用虚拟内存所需要的特性支持应用程序使用虚拟内存的系统调用虚拟内存系统如何支持用户应用程序构建大的缓存表Bakers Real-Time Copying Garbage Collector使用虚拟内存特性的GC使用虚拟内存特性的GC代码展示 引言…

【Linux后端服务器开发】基础IO与文件系统

目录 一、基础IO 1. C语言文件读写 2. 标志位传参 3. C语言与系统调用关系 二、文件系统 1. 文件描述符 2. 输入输出重定向 一、基础IO 文件调用 库函数接口&#xff1a; fopen、fclose、fwrite、fread、fseek系统调用接口&#xff1a;open、close、write、read、lsee…

利用 kube-vip 实现 K3s 高可用部署

作者简介 王海龙&#xff0c;Rancher 中国社区技术经理&#xff0c;Linux Foundation APAC Evangelist&#xff0c;负责 Rancher 中国技术社区的维护和运营。拥有 9 年的云计算领域经验&#xff0c;经历了 OpenStack 到 Kubernetes 的技术变革&#xff0c;无论底层操作系统 Lin…

腾讯音乐娱乐集团2023校园招聘技术类岗位编程题合集

字符串操作 题解&#xff1a;先变为没出现过的字符&#xff0c;然后在正常的变换 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** 返回满足题意的最小操作数* param str string字符串 给定…

Python绘制直方图

文章目录 初步参数绘图类型多组数据直方图对比 初步 对于大量样本来说&#xff0c;如果想快速获知其分布特征&#xff0c;最方便的可视化方案就是直方图&#xff0c;即统计落入不同区间中的样本个数。 以正态分布为例 import numpy as np import matplotlib.pyplot as pltxs…