美文网首页
Qt开发技术:Q3D图表开发笔记(一):Q3DScatter三维

Qt开发技术:Q3D图表开发笔记(一):Q3DScatter三维

作者: 红模仿_红胖子 | 来源:发表于2023-03-13 11:15 被阅读0次

前言

qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。

其中就包括华丽绚烂的三维图表,数据量不大的时候是可以使用的。

Demo:Q3DScatter散点图演示效果

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=newQScatter3DSeries;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>usingnamespaceQtDataVisualization;intmain(intargc,char**argv){QGuiApplicationapp(argc,argv);Q3DScatter scatter;scatter.setFlags(scatter.flags()^Qt::FramelessWindowHint);QScatter3DSeries*series=newQScatter3DSeries;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();returnapp.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=newQ3DScatter();_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=newQScatter3DSeries(_pQ3DScatter);// 设置渲染平滑_pScatter3DSeries->setMeshSmooth(true);// 视图添加该曲线_pQ3DScatter->addSeries(_pScatter3DSeries);// 设置阴影质量_pQ3DScatter->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);// 设置视角_pQ3DScatter->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);// 设置子网格_pQ3DScatter->activeTheme()->setGridEnabled(true);#if1// 添加模拟数据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#if1// 模拟QList<QVector3D>listVector3D;#if0listVector3D<<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

Demo源码

Q3dScatterWidget.h

#ifndefQ3DSCATTERWIDGET_H#defineQ3DSCATTERWIDGET_H#include<QWidget>#include<Q3DScatter>#include<Q3DTheme>#include<QScatter3DSeries>#include<QVector3D>usingnamespaceQtDataVisualization;namespaceUi{classQ3dScatterWidget;}classQ3dScatterWidget:publicQWidget{Q_OBJECTpublic:explicitQ3dScatterWidget(QWidget*parent=0);~Q3dScatterWidget();public:voidsetData(QList<QVector3D>listVector3D);protected:voidinitControl();protected:voidresizeEvent(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")#defineLOGqDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")Q3dScatterWidget::Q3dScatterWidget(QWidget*parent):QWidget(parent),ui(newUi::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(){deleteui;}voidQ3dScatterWidget::setData(QList<QVector3D>listVector3D){doublexMin,xMax,yMin,yMax,zMin,zMax;QScatterDataArray data;for(intindex=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);}voidQ3dScatterWidget::initControl(){_pQ3DScatter=newQ3DScatter();_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=newQScatter3DSeries(_pQ3DScatter);// 设置渲染平滑_pScatter3DSeries->setMeshSmooth(true);// 视图添加该曲线_pQ3DScatter->addSeries(_pScatter3DSeries);// 设置阴影质量_pQ3DScatter->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);// 设置视角_pQ3DScatter->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);// 设置子网格_pQ3DScatter->activeTheme()->setGridEnabled(true);#if1// 添加模拟数据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#if1// 模拟QList<QVector3D>listVector3D;#if0listVector3D<<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}voidQ3dScatterWidget::resizeEvent(QResizeEvent*event){if(_pContainer){_pContainer->setGeometry(rect());}}

工程模板

入坑

入坑一:找不到Q3DScatter类

问题

原因

  有命名空间。

解决

usingnamespaceQtDataVisualization;

相关文章

网友评论

      本文标题:Qt开发技术:Q3D图表开发笔记(一):Q3DScatter三维

      本文链接:https://www.haomeiwen.com/subject/iyrcrdtx.html