若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/129520187

各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

Qt开发专栏:开发技术(点击传送门)

上一篇:无
下一篇:敬请期待…

前言

  qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。
  其中就包括华丽绚烂的三维图表,数据量不大的时候是可以使用的。

Demo:Q3DScatter散点图演示效果

  
  
  

下载地址:

  Demo v1.0.0运行包下载地址:https://download.csdn.net/download/qq21497936/87575673
  QQ群下载:请点击博客主头像,可进入博客首页,查看右侧,有QQ群联系方式,(点击“文件”搜索“q3d”,群内与博文同步更新)
  百度网盘下载地址:https://pan.baidu.com/s/1sM1xSY-VOpr7kZPyrWmclg?pwd=1234

Q3D提供的三维图表

  依赖QtDataVisualization。在安装qt的时候要选择安装QtDataVisualization模块。

Q3DScatter散点图

  Q3D的散点图,性能大约支撑1000个点可以不卡顿,具体依赖pc,1000个点是什么 概念,可以理解为:10x10x10的区域,每个区域一个数据点。
  

Q3DBars柱状图

  Q3D的柱状图,性能跟散点图类似。
  

Q3DSurface平面凹凸图,平面纹理图

  Q3D的柱状图,性能跟散点图类似。
  

Q3DScatter散点图

简介

  Q3DScatter类提供了渲染3D散点图的方法。能够在3D中渲染散点图,并通过自由旋转场景来查看散点图。
  旋转是通过按住鼠标右键并移动鼠标来完成的。缩放由鼠标滚轮完成。如果启用,则通过鼠标左键进行选择。通过单击鼠标滚轮,可以将场景重置为默认摄影机视图。在触摸设备中,旋转是通过点击和移动完成的,选择是通过点击并按住并缩放。
  如果没有设置轴,将创建没有标签的临时默认轴。这些默认轴可以通过轴访问器进行修改,但是一旦为方向明确设置了任何轴,该方向的默认轴就会被破坏。
  Q3DScatter支持同时显示多个系列。

构造最小Q3DS散点图

  首先,构建Q3DS散射器。由于在本例中我们将图形作为顶级窗口运行,因此需要清除Qt::FramelessWindowHint标志,该标志默认设置为:

Q3DScatter scatter;
scatter.setFlags(scatter.flags() ^ Qt::FramelessWindowHint);

  现在Q3DScatter已准备好接收要渲染的数据。添加一系列3个QVector3D项目:

QScatter3DSeries *series = new QScatter3DSeries;
QScatterDataArray data;
data << QVector3D(0.5f, 0.5f, 0.5f) << QVector3D(-0.3f, -0.5f, -0.4f) << QVector3D(0.0f, -0.3f, 0.2f);
series->dataProxy()->addItems(data);
scatter.addSeries(series);

  最后,将其设置为可见:

scatter.show();

  创建和显示此图形所需的完整代码是:

#include <QtDataVisualization>using namespace QtDataVisualization;int main(int argc, char **argv)
{QGuiApplication app(argc, argv);Q3DScatter scatter;scatter.setFlags(scatter.flags() ^ Qt::FramelessWindowHint);QScatter3DSeries *series = new QScatter3DSeries;QScatterDataArray data;
data << QVector3D(0.5f, 0.5f, 0.5f) << QVector3D(-0.3f, -0.5f, -0.4f)<< QVector3D(0.0f, -0.3f, 0.2f);series->dataProxy()->addItems(data);scatter.addSeries(series);scatter.show();return app.exec();
}

  运行效果:
  
  场景可以被旋转、放大,并且可以选择一个项目来查看其位置,但在这个最小的代码示例中不包括其他交互。通过熟悉所提供的示例(如散点示例)来了解更多信息。

Q3Ddemo构建流程解析

步骤一:确认安装QtDataVisualization模块

  如何确认,则是在帮助文件中查看是否有Q3dscatter类。一般是安装了模块才会有对应的帮助文件。没有则重新安装qt或者单独安装该模块。
  

步骤二:工程配置文件中加入模块

  Q3d是在数据可视化模块中,需要在pro或者pri配置文件中添加。

QT += datavisualization

  

步骤三:添加使用到的头文件

  使用到Q3DScatter相关类中添加头文件,主要使用到Q3DScatter和QScatter3DSeries等等。

#include <Q3DScatter>
#include <Q3DTheme>
#include <QScatter3DSeries>
#include <QVector3D>

  

步骤四:添加命名空间

  这时候还是无法使用对应的类,需要添加命名空间才行,查看最后“入坑一”:

using namespace QtDataVisualization;

  

步骤五:Q3D的图标基础构建框架

  下面是包含注释的Q3DScatter基础构建流程,其他两种图类似:

_pQ3DScatter = new Q3DScatter();
_pContainer = QWidget::createWindowContainer(_pQ3DScatter, this);// 设置轴文本
{_pQ3DScatter->axisX()->setTitle("X");_pQ3DScatter->axisY()->setTitle("Y");_pQ3DScatter->axisZ()->setTitle("Z");
}
// 设置轴范围
{//        _pQ3DScatter->axisX()->setRange(0, 10);
//        _pQ3DScatter->axisY()->setRange(0, 10);
//        _pQ3DScatter->axisZ()->setRange(0, 10);
}// 生成一个曲线
_pScatter3DSeries = new QScatter3DSeries(_pQ3DScatter);
// 设置渲染平滑
_pScatter3DSeries->setMeshSmooth(true);// 视图添加该曲线
_pQ3DScatter->addSeries(_pScatter3DSeries);// 设置阴影质量
_pQ3DScatter->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
// 设置视角
_pQ3DScatter->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);
// 设置子网格
_pQ3DScatter->activeTheme()->setGridEnabled(true);#if 1
// 添加模拟数据
QScatterDataArray data;
data << QVector3D(1, 1,1) << QVector3D(1, 1, 2) << QVector3D(1, 1, 3)<< QVector3D(1, 2,1) << QVector3D(1, 2, 2) << QVector3D(1, 2, 3)<< QVector3D(1, 3,1) << QVector3D(1, 3, 2) << QVector3D(1, 3, 3);
// 添加数据(自动冲掉之前的数据)
_pScatter3DSeries->dataProxy()->addItems(data);
#endif#if 1
// 模拟
QList<QVector3D> listVector3D;
#if 0
listVector3D <<  QVector3D(5, 1,1) << QVector3D(5, 1, 2) << QVector3D(5, 1, 3)<< QVector3D(5, 2,1) << QVector3D(5, 2, 2) << QVector3D(5, 2, 3)<< QVector3D(5, 3,1) << QVector3D(5, 3, 2) << QVector3D(5, 3, 3);
#else
listVector3D << QVector3D(1, 1,1) << QVector3D(1, 1, 2) << QVector3D(1, 1, 3)<< QVector3D(1, 2,1) << QVector3D(1, 2, 2) << QVector3D(1, 2, 3)<< QVector3D(1, 3,1) << QVector3D(1, 3, 2) << QVector3D(1, 3, 3);
#endif

Demo源码

Q3dScatterWidget.h

#ifndef Q3DSCATTERWIDGET_H
#define Q3DSCATTERWIDGET_H#include <QWidget>
#include <Q3DScatter>
#include <Q3DTheme>
#include <QScatter3DSeries>
#include <QVector3D>using namespace QtDataVisualization;namespace Ui {class Q3dScatterWidget;
}class Q3dScatterWidget : public QWidget
{Q_OBJECTpublic:explicit Q3dScatterWidget(QWidget *parent = 0);~Q3dScatterWidget();public:void setData(QList<QVector3D> listVector3D);protected:void initControl();protected:void resizeEvent(QResizeEvent *event);private:Ui::Q3dScatterWidget *ui;private:Q3DScatter *_pQ3DScatter;               // q3d散点视图QWidget *_pContainer;                   // q3d窗口容器QScatter3DSeries *_pScatter3DSeries;    // q3d散点图数据
};#endif // Q3DSCATTERWIDGET_H

Q3dScatterWidget.cpp

#include "Q3dScatterWidget.h"
#include "ui_Q3dScatterWidget.h"
#include <Q3DTheme>#include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")Q3dScatterWidget::Q3dScatterWidget(QWidget *parent) :QWidget(parent),ui(new Ui::Q3dScatterWidget),_pQ3DScatter(0),_pContainer(0),_pScatter3DSeries(0)
{ui->setupUi(this);QString version = "v1.0.0";setWindowTitle(QString("q3d散点图示例 %1(作者:长沙红胖子 QQ:21497936 WX:15173255813 www.hpzwl.com").arg(version));initControl();
}Q3dScatterWidget::~Q3dScatterWidget()
{delete ui;
}void Q3dScatterWidget::setData(QList<QVector3D> listVector3D)
{double xMin, xMax, yMin, yMax, zMin, zMax;QScatterDataArray data;for(int index = 0; index < listVector3D.size(); index++){// 添加模拟数据data << listVector3D.at(index);// 计算范围if(index == 0){xMin = listVector3D.at(index).x();xMax = listVector3D.at(index).x();yMin = listVector3D.at(index).y();yMax = listVector3D.at(index).y();zMin = listVector3D.at(index).z();zMax = listVector3D.at(index).z();}else {if(xMin > listVector3D.at(index).x() + 1e-8){xMin = listVector3D.at(index).x();}if(xMax < listVector3D.at(index).x() - 1e-8){xMax = listVector3D.at(index).x();}if(yMin > listVector3D.at(index).y() + 1e-8){yMin = listVector3D.at(index).y();}if(yMax < listVector3D.at(index).y() - 1e-8){yMax = listVector3D.at(index).y();}if(zMin > listVector3D.at(index).z() + 1e-8){zMin = listVector3D.at(index).z();}if(zMax < listVector3D.at(index).z() - 1e-8){zMax = listVector3D.at(index).z();}}}// 添加数据(自动冲掉之前的数据)_pScatter3DSeries->dataProxy()->addItems(data);// 计算范围 x轴范围要大于等于y轴if(xMax - xMin < yMax - yMin){xMax = xMin + (yMax - yMin);}_pQ3DScatter->axisX()->setRange(xMin, xMax);_pQ3DScatter->axisY()->setRange(yMin, yMax);_pQ3DScatter->axisZ()->setRange(zMin, zMax);
}void Q3dScatterWidget::initControl()
{_pQ3DScatter = new Q3DScatter();_pContainer = QWidget::createWindowContainer(_pQ3DScatter, this);// 设置轴文本{_pQ3DScatter->axisX()->setTitle("X");_pQ3DScatter->axisY()->setTitle("Y");_pQ3DScatter->axisZ()->setTitle("Z");}// 设置轴范围{//        _pQ3DScatter->axisX()->setRange(0, 10);
//        _pQ3DScatter->axisY()->setRange(0, 10);
//        _pQ3DScatter->axisZ()->setRange(0, 10);}// 生成一个曲线_pScatter3DSeries = new QScatter3DSeries(_pQ3DScatter);// 设置渲染平滑_pScatter3DSeries->setMeshSmooth(true);// 视图添加该曲线_pQ3DScatter->addSeries(_pScatter3DSeries);// 设置阴影质量_pQ3DScatter->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);// 设置视角_pQ3DScatter->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);// 设置子网格_pQ3DScatter->activeTheme()->setGridEnabled(true);#if 1// 添加模拟数据QScatterDataArray data;data << QVector3D(1, 1,1) << QVector3D(1, 1, 2) << QVector3D(1, 1, 3)<< QVector3D(1, 2,1) << QVector3D(1, 2, 2) << QVector3D(1, 2, 3)<< QVector3D(1, 3,1) << QVector3D(1, 3, 2) << QVector3D(1, 3, 3);// 添加数据(自动冲掉之前的数据)_pScatter3DSeries->dataProxy()->addItems(data);
#endif#if 1// 模拟QList<QVector3D> listVector3D;
#if 0listVector3D <<  QVector3D(5, 1,1) << QVector3D(5, 1, 2) << QVector3D(5, 1, 3)<< QVector3D(5, 2,1) << QVector3D(5, 2, 2) << QVector3D(5, 2, 3)<< QVector3D(5, 3,1) << QVector3D(5, 3, 2) << QVector3D(5, 3, 3);
#elselistVector3D << QVector3D(1, 1,1) << QVector3D(1, 1, 2) << QVector3D(1, 1, 3)<< QVector3D(1, 2,1) << QVector3D(1, 2, 2) << QVector3D(1, 2, 3)<< QVector3D(1, 3,1) << QVector3D(1, 3, 2) << QVector3D(1, 3, 3);
#endif// 添加数据setData(listVector3D);
#endif
}void Q3dScatterWidget::resizeEvent(QResizeEvent *event)
{if(_pContainer){_pContainer->setGeometry(rect());}
}

工程模板

  

入坑

入坑一:找不到Q3DScatter类

问题

  

原因

  有命名空间。

解决

using namespace QtDataVisualization;

上一篇:无
下一篇:敬请期待…

若该文为原创文章,转载请注明原文出处
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/129520187

Qt开发技术:Q3D图表开发笔记(一):Q3DScatter三维散点图介绍、Demo以及代码详解相关推荐

  1. Qt开发技术:Q3D图表开发笔记(二):Q3DBar三维柱状图介绍、Demo以及代码详解

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130150728 各位读者,知识无穷而人力有穷,要么改需 ...

  2. Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130264470 各位读者,知识无穷而人力有穷,要么改需 ...

  3. Qt开发技术:QCharts(三)QCharts样条曲线图介绍、Demo以及代码详解

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108022984 各位读者,知识无穷而人力有穷 ...

  4. qchart折现图_Qt开发技术:QCharts(二)QCharts折线图介绍、Demo以及代码详解

    若该文为原创文章,未经允许不得转载 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 敬请期待- 红胖子,来也! 介绍了整体框架,开始动手码代码,按照顺序,从折线图开始. QCh ...

  5. SLAM学习笔记(二十)LIO-SAM流程及代码详解(最全)

    写在前面 关于安装配置,博客LIO_SAM实测运行,论文学习及代码注释[附对应google driver数据] 我觉得已经写的比较完善了.但是我觉得在注释方面,这位博主写的还不够完善,因此在学习以后, ...

  6. SAP UI5 应用开发教程之一百零二 - SAP UI5 应用的打印(Print)功能实现详解试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 作者简介 Jerry Wang,2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今.Jerry 是 SAP 社区导师,S ...

  7. FPGA项目开发:204B实战应用-LMK04821代码详解(二)

    大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注FPGA技术江湖,在"闯荡江湖"."行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢. ...

  8. android生命周期_Android开发 View的生命周期结合代码详解

    咱们以TextView控件为例: /** * Created by SunshineBoy on 2020/9/23. */ public class TestTextView extends and ...

  9. LoRa节点开发:5、代码详解LoRaWAN中的几种数据包(发送与接收数据)

    本文来源微信公众号[物联网思考] 本文主要结合LoRaNode SDK v4.4.2和LoRaWAN规范1.0.3来展开. 1.数据包类型 LoRaWAN规范中有不同的数据包,通过MType字段区分, ...

最新文章

  1. RunnableException与CheckedException
  2. Vim快捷输出查找寄存器的内容(去除\,\和\V)
  3. 4个mos管驱动的全桥电路原理_最经典MOS管电路工作原理及详解没有之一
  4. 如何使用gnvm自动更新Windows10操作系统上的nodejs
  5. java函数只有参数类不一样_java的函数参数传递
  6. asp.net安全身份验证
  7. mysql中文坑爹的东西
  8. 计算机财会属于经济管理类吗,哪些专业可以考公务员
  9. android 一键新机,改机概述 xposed 改机缺点
  10. 计算机网卡和交换机网卡以及交换机数据转发
  11. MATLAB编写m函数理解 y=f(g(x))*h(x)
  12. 在注册表里查找classid
  13. 5-2. 已有的小车实现samba文件共享
  14. 一个手机里登录2个微信号(微信双开)
  15. 网络能力认证CCSC-管理1级 技术1级别
  16. 死锁的处理-避免死锁
  17. python如何安装keras和tensorflow
  18. CLIP论文笔记--《Learning Transferable Visual Models From Natural Language Supervision》
  19. 如何使用 dlv 结合 Goland 进行程序 debug 调试
  20. 模板应用到多个主机 zabbix_玩转zabbix之快速入门,超全组件讲解

热门文章

  1. [绍棠] iphone手机机型判断
  2. java 以二进制读取文件_JAVA中读取文件(二进制,字符)内容的几种方法总结
  3. oracle报错数据复数,Oracle数据库设计策略及规范
  4. 成就你一生的100个哲理21-30
  5. nginx工作原理和实现高并发请求的原因
  6. 【在线网课】Java高性能高并发秒杀系统方案优化实战
  7. window操作系统搭建Spark开发调试环境
  8. VS:无法打开文件opencv_world341d.lib
  9. EasyCVR接入Ehome协议的设备,无法观看设备录像是什么原因?
  10. AI人脸检测/安全帽检测智能分析网关告警消息配置——微信告警消息配置