QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家

本文主要是介绍QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家

简介

本文将介绍QT数据可视化框架编程实战之三维曲面图,本文通过构造一个数据实时变化的三维曲面图的应用实例来展示QT数据可视化框架的数据展示能力,同时还将给出这个应用实例的C++源码和QML源码。

文章目录

  • QT三维曲面图展示实时变化数据的运行效果
  • QT三维曲面图展示实时变化数据的设计思路
  • QT三维曲面图展示实时变化数据的C++主程序
  • QT三维曲面图展示实时变化数据的数据源C++源码
  • QT三维曲面图展示实时变化数据的QML源码

正文

QT三维曲面图展示实时变化数据的运行效果

QT数据可视化框架中的三维曲面图,展示实时变化的序列数据的运行效果截图如下所示:

在这里插入图片描述

运行效果的GIF动画如下所示:

在这里插入图片描述

运行效果和对应的源码浏览的视频如下所示:

QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家

视频链接如下所示:

QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家

QT三维曲面图展示实时变化数据的设计思路

QT数据可视化框架展示实时变化的三维曲面图,首先想到的就是动态的实时生成曲面图序列的数据点。考虑到数据点的数量可能比较多,那么为了提升运行效率,可以将实时生成曲面图序列的数据点的功能使用C++来实现,然后使用QT三维曲面图的QML组件来展示这些序列的数据,从而实现实时变化数据的展示。

为了不断生成变化的数据点,可以考虑使用QML定时器来定时更新数据点;为了及时的展示出变化之后的数据点,可以考虑使用定时器来定时刷新QT三维曲面图。

QT三维曲面图展示实时变化数据的C++主程序

butianyun.cpp文件如下所示:


int main(int argc, char *argv[])
{qputenv("QSG_RHI_BACKEND", "opengl");QGuiApplication app(argc, argv);qmlRegisterType<ButianyunDataSource>("ButianyunDataSource", 1, 0, "ButianyunDataSource");QQmlApplicationEngine engine;const QUrl url(u"qrc:/Butianyun3DSurface/Butianyun3DSurface.qml"_qs);QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,&app, []() { QCoreApplication::exit(-1); },Qt::QueuedConnection);engine.load(url);return app.exec();
}

QT三维曲面图展示实时变化数据的数据源C++源码

数据源使用C++代码来生成。
ButianyunDataSource.cpp文件和ButianyunDataSource.h文件实现了数据源生成功能。

(备注:本文广泛参考了QT框架提供的QT可视化框架的例程的源码)

生成新的数据点的C++代码如下所示:

void ButianyunDataSource::generateData(int cacheCount, int rowCount, int columnCount,float xMin, float xMax,float yMin, float yMax,float zMin, float zMax)
{if (!cacheCount || !rowCount || !columnCount){return;}clearData();// 重建缓存数据m_data.resize(cacheCount);for (int i = 0; i < cacheCount; ++i){QSurfaceDataArray &array = m_data[i];array.reserve(rowCount);for (int j = 0; j < rowCount; ++j){array.append(new QSurfaceDataRow(columnCount));}}float xRange = xMax - xMin;float yRange = yMax - yMin;float zRange = zMax - zMin;int cacheIndexStep = columnCount / cacheCount;float cacheStep = float(cacheIndexStep) * xRange / float(columnCount);// 每次生成数据时一次性生成多个序列数据// 遍历缓存:缓存中的每一个序列数据就是用于某一次展示,也就是一个序列auto *generator = QRandomGenerator::global();for (int i = 0; i < cacheCount; ++i){QSurfaceDataArray &cache = m_data[i];float cacheXAdjustment = cacheStep * i;float cacheIndexAdjustment = cacheIndexStep * i;for (int j = 0; j < rowCount; ++j){QSurfaceDataRow &row = *(cache[j]);float rowMod = (float(j)) / float(rowCount);float yRangeMod = yRange * rowMod;float zRangeMod = zRange * rowMod;float z = zRangeMod + zMin;qreal rowColWaveAngleMul = M_PI * M_PI * rowMod;float rowColWaveMul = yRangeMod * 0.2f;for (int k = 0; k < columnCount; k++){float colMod = (float(k)) / float(columnCount);float xRangeMod = xRange * colMod;float x = xRangeMod + xMin + cacheXAdjustment;float colWave = float(qSin((2.0 * M_PI * colMod) - (1.0 / 2.0 * M_PI)) + 1.0);float y = (colWave * ((float(qSin(rowColWaveAngleMul * colMod) + 1.0))))* rowColWaveMul+ generator->bounded(0.03f) * yRangeMod+ generator->bounded(0.03f) * (zRange - zRangeMod);int index = k + cacheIndexAdjustment;if (index >= columnCount){index -= columnCount;x -= xRange;}row[index] = QVector3D(x, y, z);}}}
}

刷新QT三维曲面图的序列的C++代码如下所示:


void ButianyunDataSource::update(QSurface3DSeries *series)
{if (series && !m_data.isEmpty()){// 缓存数据的索引序号if (++m_index >= m_data.size()){m_index = 0;}const QSurfaceDataArray &array = m_data.at(m_index);int newRowCount = array.size();int newColumnCount = array.at(0)->size();// 重新序列重构数据if (!m_resetArray || series->dataProxy()->rowCount() != newRowCount|| series->dataProxy()->columnCount() != newColumnCount){m_resetArray = new QSurfaceDataArray();m_resetArray->reserve(newRowCount);for (int i = 0; i < newRowCount; ++i){m_resetArray->append(new QSurfaceDataRow(newColumnCount));}}// 从缓存中拷贝数据到序列重构数据中for (int i = 0; i < newRowCount; ++i){const QSurfaceDataRow &sourceRow = *(array.at(i));QSurfaceDataRow &row = *(*m_resetArray)[i];std::copy(sourceRow.cbegin(), sourceRow.cend(), row.begin());}// 通知代理对象:序列的数据已经变化了,以便刷新界面series->dataProxy()->resetArray(m_resetArray);}
}

QT三维曲面图展示实时变化数据的QML源码

Butianyun3DSurface.qml文件源码如下所示:

Window {width: 1920height: 1000visible: truetitle: qsTr("QT数据可视化  补天云QT系列视频课程 补天云QT技术培训专家")//数据源ButianyunDataSource {id: dataSource}//QML三维曲面Surface3D {id: surfaceGraphanchors.fill: parent//QML三维曲面的序列Surface3DSeries {id: surfaceSeriesdrawMode: Surface3DSeries.DrawSurfaceflatShadingEnabled: falseitemLabelFormat: "@xLabel, @zLabel: @yLabel"itemLabelVisible: false}shadowQuality: AbstractGraph3D.ShadowQualityNoneselectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndColumntheme: Theme3D {type: Theme3D.ThemeIsabellebackgroundEnabled: false}scene.activeCamera.cameraPreset: Camera3D.CameraPresetBehindaxisX.labelFormat: "%d ms"axisY.labelFormat: "%d mm"axisZ.labelFormat: "%d mm"axisX.min: 0axisY.min: 0axisZ.min: 0axisX.max: 1000axisY.max: 1000axisZ.max: 1000axisX.segmentCount: 10axisY.segmentCount: 10axisZ.segmentCount: 10measureFps: truerenderingMode: AbstractGraph3D.RenderDirectToBackground//首次产生数据Component.onCompleted: generateData();}property int cacheCount: 15property int fps:  30property int rowCount:  30property int columnCount: 30//产生数据的包装函数function generateData() {dataSource.generateData(cacheCount, rowCount,columnCount,surfaceGraph.axisX.min, surfaceGraph.axisX.max,surfaceGraph.axisY.min, surfaceGraph.axisY.max,surfaceGraph.axisZ.min, surfaceGraph.axisZ.max);}//定时器:定时重新产生数据Timer {interval: 1000running: truerepeat: trueonTriggered: {generateData();}}//定时器:定时刷新曲面界面Timer {interval: 1000 / fpsrunning: truerepeat: trueonTriggered: {dataSource.update(surfaceSeries);}}}

总结

本文介绍了QT数据可视化框架编程实战之三维曲面图,本文通过构造一个数据实时变化的三维曲面图的应用实例来展示QT数据可视化框架的数据展示能力,同时还给出了这个应用实例的C++源码和QML源码。

本文介绍的技术路线也存在进一步优化改进的空间,比如本文使用C++代码来实时生成数据点,使用的是CPU的运算能力,如果能使用GLSL之类的shader代码来实时生成数据点,则可以充分发挥GPU的运算能力,将可能更进一步提升三维曲面图应用程序的整体性能。

如果您认为这篇文章对您有所帮助,请您一定立即点赞+喜欢+收藏,本文作者将能从您的点赞+喜欢+收藏中获取到创作新的好文章的动力。如果您认为作者写的文章还有一些参考价值,您也可以关注这篇文章的作者。

这篇关于QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/341312

相关文章

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

PowerShell中15个提升运维效率关键命令实战指南

《PowerShell中15个提升运维效率关键命令实战指南》作为网络安全专业人员的必备技能,PowerShell在系统管理、日志分析、威胁检测和自动化响应方面展现出强大能力,下面我们就来看看15个提升... 目录一、PowerShell在网络安全中的战略价值二、网络安全关键场景命令实战1. 系统安全基线核查

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien