Qt开发总结(20)——Data Visualization_q3dscatter_bjtuwayne的博客-程序员秘密

技术标签: Qt  Qt5  DataVisualization  

上篇介绍了Qt Charts二维图表模块,本篇笔记总结Qt三维图表模块——Data Visualization。同样,在Qt5.7之前之后商业版才有,从Qt5.7开始免费开放在了社区版中。与QtCharts类似,也是基于Qt的Graphics View图形视图架构。当然,目前的Data Visualization还无法和一些专业的三维显示类库相提并论,但是对于一些简单的三维数据显示是比较实用的。另外,本人目前为止还未用过这个模块,所以文中不适当的地方请多包涵,也请评论区提宝贵意见。

概述

Data Visualization的三维显示功能主要由三种三维图形来实现,分别是三维柱状图Q3DBars,三维空间散点Q3DScatter,三维曲面Q3DSurface。这三个类的父类都是QAbstract3DGraph,从QWindow继承而来。

Data Visualization与Qt Charts类似都是基于Qt Graphics View的图形视图结构,所以一个三维图形也是由图表、序列、坐标轴等元素构成。响应的序列类有:QBar3DSeries,QScatter3DSeries,QSurface3DSeries类。这三个序列类是与图形类Q3DBars,Q3DScatter,Q3DSurface一一对应的。在一个图中可以有多个同类型的序列,但不能有不同类型的序列。另外,三维图形也有坐标轴类,共有两种坐标轴类:QValue3DAxis和QCategory3DAxis,前者用于数值型坐标轴,后者用于文字型坐标轴。

Data Visualization模块中还有数据代理(Data Proxies),数据代理类就是与序列对应,用于存储序列的数据的类。这也涉及一些具体的功能类:QBarDataProxy,QScatterDataProxy和QSurfaceDataProxy,这也与三种图表一一对应。

在使用时,需要在Qt工程.pro文件中加入:

QT += datavisualization

如果是VS工程,需要在Qt Settings中勾选这一模块。

在调用时源码中添加:

#include <QtDataVisualization>

using namespace QtDataVisualization;

如果你仅仅用到了其中部分头文件,比如只用到了Q3DBars,建议只include相关的几个头文件。

三维柱状图

Q3DBars实现创建图表,QBar3DSeries and QBarDataProxy用于设置序列和数据,同时可以控制可视化属性。场景默认具备旋转,缩放,可以选中某一条目等。

#include <QtWidgets/QApplication>
#include <QtDataVisualization>
using namespace QtDataVisualization;

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	//构造一个三维柱状图对象
	Q3DBars bars;
	bars.setFlags(bars.flags() ^ Qt::FramelessWindowHint);	//top level
	//设置坐标轴的显示范围
	bars.rowAxis()->setRange(0, 4);
	bars.columnAxis()->setRange(0, 4);
	//创建5行数据,放入序列,添加到图形
	QBar3DSeries *series = new QBar3DSeries;
	QBarDataRow *data = new QBarDataRow;
	*data << 1.0f << 3.0f << 7.5f << 5.0f << 2.2f;
	series->dataProxy()->addRow(data);
	bars.addSeries(series);
	bars.show();
	return a.exec();
}

 

三维散点图

Q3DScatter实现图形,QScatter3DSeries and QScatterDataProxy实现序列和数据,并控制图表的可视化属性。场景默认具备旋转,缩放,可以选中某一条目等。

#include <QtWidgets/QApplication>
#include <QtDataVisualization>
using namespace QtDataVisualization;

int main(int argc, char **argv)
{
	QGuiApplication app(argc, argv);
	//创建Q3DScatter三维散点图类对象
	Q3DScatter scatter;
	scatter.setFlags(scatter.flags() ^ Qt::FramelessWindowHint);
	//新建序列和数据,在序列中加入3个点,把序列添加到图形
	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();
}

 

三维曲面图

Q3DSurface类实现图形,QSurface3DSeries and QSurfaceDataProxy实现序列和数据,并控制可视化属性。同样,具备旋转,缩放和选中数据的基本操作。

#include <QtWidgets/QApplication>
#include <QtDataVisualization>
using namespace QtDataVisualization;

int main(int argc, char **argv)
{
	QGuiApplication app(argc, argv);
	//创建一个三维曲面对象
	Q3DSurface surface;
	surface.setFlags(surface.flags() ^ Qt::FramelessWindowHint);
	//创建数据对象
	QSurfaceDataArray *data = new QSurfaceDataArray;
	QSurfaceDataRow *dataRow1 = new QSurfaceDataRow;
	QSurfaceDataRow *dataRow2 = new QSurfaceDataRow;
	//为数据对象赋值
	*dataRow1 << QVector3D(0.0f, 0.1f, 0.5f) << QVector3D(1.0f, 0.5f, 0.5f);
	*dataRow2 << QVector3D(0.0f, 1.8f, 1.0f) << QVector3D(1.0f, 1.2f, 1.0f);
	*data << dataRow1 << dataRow2;
	//创建序列,加入数据,添加到Q3DSurface
	QSurface3DSeries *series = new QSurface3DSeries;
	series->dataProxy()->resetArray(data);
	surface.addSeries(series);
	surface.show();

	return app.exec();
}

 

数据管理

序列(Series)拥有一系列被data proxy控制的数据,可以控制可视化渲染属性,比如颜色等。每一个三维图都有它自己对应的series类。实际使用时,用户想要显示的数据通常是很多格式的,直接添加到Series中是不支持的。Qt实现了数据代理data proxies,以使得用户可以用自己熟知的类型定义数据,通过data proxies转化传递。,每一种图形也是有对应的basic proxy类型。比如,QBar3DSeries对应QBarDataProxy,QBarDataProxy中保存有QBarDataItem对象,每一个QBarDataItem对象保存一个单独的bar value。

  Q3DBars graph;
  QBarDataProxy *newProxy = new QBarDataProxy;

  QBarDataArray *dataArray = new QBarDataArray;
  dataArray->reserve(10);
  for (int i = 0; i < 10; i++) {
      QBarDataRow *dataRow = new QBarDataRow(5);
      for (int j = 0; j < 5; j++)
          (*dataRow)[j].setValue(myData->getValue(i, j));
      dataArray->append(dataRow);
  }

  newProxy->resetArray(dataArray);
  graph->addSeries(new QBar3DSeries(newProxy));

 

上述例子描述了用基本的数据代理实现自定义数据mydata对象的传递。特别的,Series对象一次只能拥有一个proxy。当有新的proxy被设置到Series后,之前的proxy会被删除。但是图表可以同时拥有多条Series,如果你想在两组数据中转换,建议用两个Series会更加有效。

因为三维绘图也是基于Model/View架构,我们当然可以用model管理数据,这也是Qt的常见方式。每个三维图类型也提供了特殊的proxy类以实现Model数据的传递。比如,QItemModelBarDataProxy则可以实现将Model数据于QBar3DSeries关联起来。这些类使用起来很简单,只需要给出Model Item的指针和如何映射到basic proxy就可以。这种映射规则类似于告诉proxy在model item中的哪个值属于哪一行,属于哪一列,哪个值表示了具体的数值等等。通常,item Models只有一种角色,但是包含了映射所需的多个值。这时候将用到item model proxies的模式匹配和自动替换技术。

  

    const VariantDataItemList &itemList = m_dataSet->itemList();
    int rowIndex = m_mapping->rowIndex();
    int columnIndex = m_mapping->columnIndex();
    int valueIndex = m_mapping->valueIndex();
    const QStringList &rowList = m_mapping->rowCategories();
    const QStringList &columnList = m_mapping->columnCategories();

    // Sort values into rows and columns
    typedef QHash<QString, float> ColumnValueMap;
    QHash <QString, ColumnValueMap> itemValueMap;
    foreach (const VariantDataItem *item, itemList) {
        itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()]
                = item->at(valueIndex).toReal();
    }

 

例子

最后上一个地形图的三维例子:https://download.csdn.net/download/bjtuwayne/12033065

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bjtuwayne/article/details/103723533

智能推荐

深度学习中的遥感影像数据集_patternnet数据集_haoji007的博客-程序员秘密

以下数据集均为网上开源数据集,若有遗误或不慎涉及侵权,烦请评论或留言联系 目前本项目共整理 场景分类数据集25个(整理完结); 目标检测数据集28+个(整理完结); 图像分割数据集33+个(整理完结); 变化数据集5个; …… 欢迎访问ai studio进行数据下载,https://aistudio.baidu.com/aistudio/projectdetail/882508 最后更新——2...

vscode调试python c++混合代码_StaRS in EyeS的博客-程序员秘密

vscode调试python c++混合代码https://nadiah.org/2020/03/01/example-debug-mixed-python-c-in-visual-studio-code/

Qt 5 下载与安装详解_qt5.5下载_蓝色的杯子的博客-程序员秘密

版本选择详见Qt文档:Porting to Qt 6 | Qt 6.1需要注意的点:在升级到 Qt 6 之前,确保Qt 5 应用程序已更新到 Qt 5.15,它移植到 Qt 6 时变化最少 Qt 5.15 中标记为弃用或过时的 API 可能已在 Qt 6.0 版本中删除 Qt 6.0 中移除的模块:removed-modules-in-qt-6-0一些目前被移除的模块,在未来的 Qt6 版本可能会恢复 Qt 6 模块的变化:Changes to Qt Modules Qt 的 LTS(L

Java尚硅谷基础笔记-day4数组-数组常见算法_alyja的博客-程序员秘密

第三章 数组3.1 数组的概述3.2 一维数组的使用3.3 多维数组的使用3.4 数组中涉及的常见算法3.5 数组工具类的使用3.6 数组使用中的常见异常3.4 数组中涉及的常见算法3.4.1数组元素的赋值练习1:杨辉三角使用二维数组打印一个 10 行杨辉三角【提示】第一行有 1 个元素, 第 n 行有 n 个元素每一行的第一个元素和最后一个元素都是 1从第三行开始, 对于非第一个元素和最后一个元素的元素。即:yanghui[i][j] = yanghui[i-1][j-

华为路由器访问控制列表ACL配置实例_acl能绑定在路由器接口上吗_把倒立的世界腾空的博客-程序员秘密

ACL配置实验拓扑实验准备实验思路实验步骤实验验证实验拓扑实验准备实验思路如果要让vlan10 ping不通vlan20,可以在R1路由器上设置普通的acl策略,阻止源为vlan10网段的ip的访问,然后把策略映射到vlan20网关的接口上如果要让R1访问不了ftp服务器,可以在R2上做扩展acl策略,源为R1的出口ip,目标为ftp服务器地址,阻止的协议是tcp的20和21端口,然后把策略应用到R2的出接口上实验步骤二层交换机上的配置[Huawei]sysname sw1

电机优化程序使用说明_moving1.torque和torque1.torque_whhxp的博客-程序员秘密

电机优化程序使用说明电机优化程序使用说明引言1编写目的2项目背景3 定义软件概述1目标2功能3 性能运行环境1硬件硬件最小配置硬件推荐配置2支持软件使用说明1安装和初始化第一步解压缩软件包到一个目录下第二步设置系统PATH变量第三步打开gaWizardexe2输入21数据背景22数据格式23输入举例几个关键的部分3输出31数据背景32数据格式33

随便推点

ExpandableListView OnChildClickListener 失效解决_expandablelistview setonchildclicklistener 无效_激流小舟的博客-程序员秘密

尝试了多次,可能是自己的代码问题。布置为啥当在ExpandableListView 的子item中加入button后,子item便不能被响应点击事件//isChildSelectable 已设置为true public boolean isChildSelectable(int groupPosition, int childPosition) { return tru

六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序_六大排序算法双鱼211_双鱼211的博客-程序员秘密

文章目录:1. 插入排序2.希尔排序1. 插入排序步骤:1.从第一个元素开始,该元素可以认为已经被排序2.取下一个元素tem,从已排序的元素序列从后往前扫描3.如果该元素大于tem,则将该元素移到下一位4.重复步骤3,直到找到已排序元素中小于等于tem的元素5.tem插入到该元素的后面,如果已排序所有元素都大于tem,则将tem插入到下标为0的位置6.重复步骤2~5动图演示如下:思路:  在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个

Visual C++6.0的安装和使用_vs c++ 6.0_张_Laura的博客-程序员秘密

【前言】最近需要使用到Visual C++6.0来写程序,下面就简单地介绍一下安装和使用【正文】下载安装可以直接下载我分享的文件,也可以自己在官网下载。链接:下载地址提取码:nswn下载之后直接傻瓜式安装就好了。使用首先建立一个工程然后新建一个文件然后就可以使用了。 感谢阅读~...

公有继承基类和派生类之间构造和析构、赋值和拷贝构造函数的关系(上)_公有继承的析构函数__200_的博客-程序员秘密

公有继承基类和派生类之间构造和析构、赋值和拷贝构造函数的关系(上)1、公有继承基类和派生类之间构造函数的关系如果一个类Text在公有继承了Object类,在创建一个Text对象t时会先调用Object的构造函数,然后再调用Text的构造函数,不论Text的形参列表声明中Object的声明在前在后。代码测试:#include&lt;iostream&gt;using namespace std;class Object{ private: int val; public: Object

Vue + ant 小技巧(前端技术面广而复杂,遇到问题后解决方法记录下来,持续更新)_vue ant_张小事Huh!的博客-程序员秘密

Vue小白,工作中长碰到一些新的知识点,前端技术面广而复杂,长记录长翻阅加深记忆

Spring Security OAuth2登录_oauth2login_ReLive27的博客-程序员秘密

对 OAuth 2.0 进行扩展,使得授权服务器和受保护资源发出的信息能够传达与用户以及他们的身份认证上下文有关的信息,我们就可以为客户端提供用于用户安全登录的所有信息。

推荐文章

热门文章

相关标签