Qt 三维柱状图 Q3DBar 和 三维条形图中的数据序列 QBar3DSeries

(一) 使用 Q3DBars 图形类和 QBar3DSeries 序列类可以绘制三维柱状图

窗口右侧是用 Q3DBars 和 QBar3DSeries 绘制的三维柱状图,这个图只有一个QBar3DSeries序列,数据是按行存储的,可以有多行。水平方向是行坐标轴和列坐标轴,使用OCategory3DAxis 坐标轴类;垂直方向是数值坐标轴,使用 QValue3DAxis 坐标轴类。在图上点击一个棒柱时,可以在图上显示其行标签、列标签和数值,状态栏上还会显示其行编号、列编号和数值。无须额外编程或设置,在图上按住鼠标右键并上下左右拖动鼠标可以进行水平和垂直方向的旋转,滚动鼠标滚轮可以进行缩放。 窗口工具栏上的按钮用于修改棒柱的基本颜色,修改选中棒柱的数值,添加、插入或删除行等。 窗口左侧是操作面板,分为多个分组框。

  • “旋转和平移”分组框。可以选择预设的三维图观察视角,可以通过 QSlider 组件进行水平旋转、垂直旋转和缩放。
  • 分组框里的4个方向按钮用于使三维柱状图在4个方向上平移,中间的按钮用于复位视角。
  • “图形总体”分组框。用于设置三维图形的主题、标签字体大小、棒柱选择模式,以及设置三维图形的各种元素的可见性和显示效果等。
  • “序列设置”分组框。设置序列的一些属性,如棒柱的样式、光滑效果等。

效果图:
在这里插入图片描述

(二) 3D部件创建及添加到窗口

1 添加三维图Q3DBars 三维图的容器QWidget和三维条形图中的数据序列QBar3DSeries

private:QWidget* graphContainer;        //三维图的容器Q3DBars* graph3D;               //三维图QBar3DSeries* series;           //三维条形图中的数据序列

2 初始化 3D部件并添加到窗口

void mainwindow::iniGraph3D()
{graph3D = new Q3DBars();            //创建三维图graphContainer = QWidget::createWindowContainer(graph3D, this);//Q3DBars继承自QWindowgraph3D->scene()->activeCamera()    //设置视角->setCameraPreset(Q3DCamera::CameraPresetFrontHigh); //设置 Z坐标轴QValue3DAxis* axisV = new QValue3DAxis; //数值坐标axisV->setTitle(QString::fromLocal8Bit("销量"));axisV->setTitleVisible(true);axisV->setLabelFormat("%d");graph3D->setValueAxis(axisV);  			 //设置数值坐标轴//设置 X坐标轴QCategory3DAxis* axisRow = new QCategory3DAxis;axisRow->setTitle("row axis");axisRow->setTitleVisible(true);graph3D->setRowAxis(axisRow);  			 //设置行坐标轴//设置 Y坐标轴QCategory3DAxis* axisCol = new QCategory3DAxis;axisCol->setTitle("column axis");axisCol->setTitleVisible(true);graph3D->setColumnAxis(axisCol);		//设置列坐标轴//创建序列series = new QBar3DSeries;series->setMesh(QAbstract3DSeries::MeshCylinder);       //棒柱形状series->setItemLabelFormat("(@rowLabel,@colLabel): %d");//项的标签显示格式graph3D->addSeries(series);//设置数据代理的数据QBarDataArray* dataArray = new QBarDataArray; //棒柱数据数组,typedef QList<QBarDataRow *> QBarDataArray;for (int i = 0; i <3; i++)   			  //行{QBarDataRow* dataRow = new QBarDataRow;   //棒柱数据行,typedef QList<QBarDataItem> QBarDataRow;for (int j = 1; j <= 5; j++)          //列{quint32 value = rand()%15+1;          //随机整数[1,15]QBarDataItem* dataItem = new QBarDataItem;//创建棒柱数据对象dataItem->setValue(value);            //设置棒柱的数据dataRow->append(*dataItem);           //添加到棒柱数据行}dataArray->append(dataRow);               //棒柱数据数组添加一个棒柱数据行}QStringList rowLabs;    //行坐标标签rowLabs << "Week1" << "Week2" << "Week3";series->dataProxy()->setRowLabels(rowLabs); //设置数据代理的行标签QStringList colLabs;    //列坐标标签colLabs << "Mon" << "Tue" << "Wed" << "Thur" << "Fri";series->dataProxy()->setColumnLabels(colLabs);//设置数据代理的列标签series->dataProxy()->resetArray(dataArray);   //重设数据代理的数据connect(series, &QBar3DSeries::selectedBarChanged,this, &mainwindow::do_barSelected);
}

2-1 设置项标签格式

如果没有为该系列显式设置数据代理,则该系列将创建默认代理。设置另一个代理将销毁现有代理以及添加到其中的所有数据。

标签格式注释
@rowTitle来自行轴的标题
@colTitle列轴的标题
@valueTitle来自值轴的标题
@rowIdx可见行索引,使用图形区域设置进行了本地化
@colIdx可见列索引,使用图形区域设置进行了本地化
@rowLabel来自行轴的标签
@colLabel来自列轴的标签
@valueLabel使用附加到图形的值轴格式格式化的项值
@seriesName系列的名称
%<format spec>指定格式的项值。使用与QValue3DAxis::abelFormat相同的规则进行格式化

3 选中棒柱

void mainwindow::do_barSelected(const QPoint& position)
{if (position.x() < 0 || position.y() < 0)  //必须加此判断{ui->actBar_ChangeValue->setEnabled(false);return;}ui->actBar_ChangeValue->setEnabled(true);const QBarDataItem* bar = series->dataProxy()->itemAt(position);QString info = QString::fromLocal8Bit("选中的棒柱,Row=%1, Column=%2, Value=%3").arg(position.x()).arg(position.y()).arg(bar->value());ui->statusBar->showMessage(info);
}

(三) 3D部件创建及添加到窗口

1 序列颜色 - 设置序列基本颜色

void mainwindow::on_actSeries_BaseColor_triggered()
{//设置序列基本颜色QColor  color = series->baseColor();color = QColorDialog::getColor(color);if (color.isValid()){series->setBaseColor(color);}        
}

2 重新生成 - 重新生成数据画图

void mainwindow::on_actRedraw_triggered()
{QBarDataProxy* dataProxy = new QBarDataProxy;    //新建数据代理int rowCount = series->dataProxy()->rowCount();  //数据代理的行数for (int i = 0; i < rowCount; i++)  //行{QBarDataRow* dataRow = new QBarDataRow;       //棒柱数据行for (int j = 1; j <= 5; j++)     //列{quint32 value = rand() % (15 - 5 + 1) + 5;QBarDataItem* dataItem = new QBarDataItem;   //数据项dataItem->setValue(value);dataRow->append(*dataItem);}QString rowStr = QString::fromLocal8Bit("第%1周").arg(i + 1);dataProxy->addRow(dataRow, rowStr);     //添加行数据和标签}QStringList colLabs = series->dataProxy()->columnLabels();    //原来的列坐标轴标签dataProxy->setColumnLabels(colLabs);series->dataProxy()->resetArray();  //清除数据代理和坐标轴标签,必须清除,否则不能重新设置坐标轴标签series->setDataProxy(dataProxy);    //重新设置数据代理,会删除之前的数据代理
}

3 修改数值 - 修改选中棒柱的数值(F2)

void mainwindow::on_actBar_ChangeValue_triggered()
{QPoint position = series->selectedBar();if (position.x() < 0 || position.y() < 0)   //必须加此判断return;QBarDataItem bar = *(series->dataProxy()->itemAt(position));qreal value = bar.value();    //原来的值bool ok;value = QInputDialog::getInt(this, QString::fromLocal8Bit("输入数值"),QString::fromLocal8Bit("更改棒柱数值"), value, 0, 50, 1, &ok);if (ok){bar.setValue(value);series->dataProxy()->setItem(position, bar);}
}

4 添加行 - 添加一行

void mainwindow::on_actData_Add_triggered()
{//添加行const QString rowLabel = QInputDialog::getText(this,QString::fromLocal8Bit("输入字符串"),QString::fromLocal8Bit("请输入行标签"));if (rowLabel.isEmpty())return;QBarDataRow* dataRow = new QBarDataRow;       //棒柱数据行for (int j = 1; j <= 5; j++)     //固定5列{quint32 value = rand()%(25 - 15 + 1) + 15;QBarDataItem* dataItem = new QBarDataItem;dataItem->setValue(value);dataRow->append(*dataItem);}series->dataProxy()->addRow(dataRow, rowLabel);     //添加棒柱数据行和标签}

5 插入行 - 插入一行

void mainwindow::on_actData_Insert_triggered()
{//插入行QString rowLabel = QInputDialog::getText(this, QString::fromLocal8Bit("输入字符串"), QString::fromLocal8Bit("请输入行标签"));if (rowLabel.isEmpty())return;QPoint position = series->selectedBar();int index = position.x(); //当前行号if (index < 0)index = 0;QBarDataRow* dataRow = new QBarDataRow;       //棒柱数据行for (int j = 1; j <= 5; j++)     //固定5列{quint32 value = rand() % (30 - 20) + 20; QBarDataItem* dataItem = new QBarDataItem;dataItem->setValue(value);dataRow->append(*dataItem);}series->dataProxy()->insertRow(index, dataRow);    //插入棒柱数据行}

6 删除行 - 删除当前行

void mainwindow::on_actData_Delete_triggered()
{QPoint position = series->selectedBar();if (position.x() < 0 || position.y() < 0)return;int rowIndex = position.x();  //当前行号int removeCount = 1;          //删除的行数int removeLabels = true;      //是否删除行标签series->dataProxy()->removeRows(rowIndex, removeCount, removeLabels);
}

7 退出 - 退出本程序

void mainwindow::on_actQiut_triggered()
{QApplication::quit();
}

(四) “旋转和平移”分组框功能

1 预设视角

void mainwindow::on_comboCamera_currentIndexChanged(int index)
{Q3DCamera::CameraPreset  cameraPos =  Q3DCamera::CameraPreset(index);graph3D->scene()->activeCamera()->setCameraPreset(cameraPos);
}

预设视角类型参考 enum Q3DCamera::CameraPreset

2 水平旋转

void mainwindow::on_sliderH_valueChanged(int value)
{graph3D->scene()->activeCamera()->setXRotation(value);
}

3 垂直旋转

void mainwindow::on_sliderV_valueChanged(int value)
{graph3D->scene()->activeCamera()->setYRotation(value);
}

4 缩放

void mainwindow::on_sliderZoom_valueChanged(int value)
{graph3D->scene()->activeCamera()->setZoomLevel(value);
}

5 下移

void mainwindow::on_btnMoveDown_clicked()
{QVector3D target3D = graph3D->scene()->activeCamera()->target();qreal z = target3D.z();target3D.setZ(z + 0.1);graph3D->scene()->activeCamera()->setTarget(target3D);
}

6 上移

void mainwindow::on_btnMoveUp_clicked()
{QVector3D target3D = graph3D->scene()->activeCamera()->target();qreal z = target3D.z();target3D.setZ(z - 0.1);graph3D->scene()->activeCamera()->setTarget(target3D);
}

7 左移

void mainwindow::on_btnMoveLeft_clicked()
{QVector3D target3D = graph3D->scene()->activeCamera()->target();qreal x = target3D.x();target3D.setX(x + 0.1);graph3D->scene()->activeCamera()->setTarget(target3D);
}

8 右移

void mainwindow::on_btnMoveRight_clicked()
{QVector3D target3D = graph3D->scene()->activeCamera()->target();qreal x = target3D.x();target3D.setX(x - 0.1);graph3D->scene()->activeCamera()->setTarget(target3D);
}

9 复位(到 FrontHigh 视角)

void mainwindow::on_btnResetCamera_clicked()
{graph3D->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFrontHigh);

(五) “图形总体”分组框功能

1 显示选中棒柱的标签 CheckBox

void mainwindow::on_cBoxTheme_currentIndexChanged(int index)
{Q3DTheme* currentTheme = graph3D->activeTheme();currentTheme->setType(Q3DTheme::Theme(index));
}

2 轴标签字体大小

void mainwindow::on_spinFontSize_valueChanged(int arg1)
{QFont font = graph3D->activeTheme()->font();font.setPointSize(arg1);graph3D->activeTheme()->setFont(font);   
}

3 选择模式

void mainwindow::on_cBoxSelectionMode_currentIndexChanged(int index)
{graph3D->setSelectionMode(QAbstract3DGraph::SelectionFlags(index));
}

4 显示背景 CheckBox

void mainwindow::on_chkBoxBackground_clicked(bool checked)
{graph3D->activeTheme()->setBackgroundEnabled(checked);
}

4-1 选择模式

enum QAbstract3DGraph::SelectionFlag

枚举值含义
QAbstract3DGraph::SelectionNone不允许选择
QAbstract3DGraph::SelectionItem选择并且高亮显示一个项
QAbstract3DGraph::SelectionRow选择并且高亮显示一行
QAbstract3DGraph::SelectionItemAndRow选择一个项和一行,用不同颜色高亮显示
QAbstract3DGraph::SelectionColumn选择并且高亮显示一列
QAbstract3DGraph::SelectionItemAndColumn选择一个项和一列,用不同颜色高亮显示
QAbstract3DGraph::SelectionRowAndColumn选择交叉的一行和一列
QAbstract3DGraph::SelectionItemRowAndColumn选择交叉的一行和一列,用不同颜色高亮显示
QAbstract3DGraph::SelectionSlice切片选择,需要与 SelectionRow 或 SelectionColumn 结合使用
QAbstract3DGraph::SelectionMultiSeries选中同一个位置处的多个序列的项

5 显示背景网格 CheckBox

void mainwindow::on_chkBoxGrid_clicked(bool checked)
{graph3D->activeTheme()->setGridEnabled(checked);
}

6 显示倒影 CheckBox

void mainwindow::on_chkBoxReflection_clicked(bool checked)
{graph3D->setReflection(checked);
}

7 数值坐标轴反向 CheckBox

void mainwindow::on_chkBoxReverse_clicked(bool checked)
{graph3D->valueAxis()->setReversed(checked);
}

8 显示轴标题 CheckBox

void mainwindow::on_chkBoxAxisTitle_clicked(bool checked)
{graph3D->valueAxis()->setTitleVisible(checked);graph3D->rowAxis()->setTitleVisible(checked);graph3D->columnAxis()->setTitleVisible(checked);
}

9 显示轴标签背景 CheckBox

void mainwindow::on_chkBoxAxisBackground_clicked(bool checked)
{graph3D->activeTheme()->setLabelBackgroundEnabled(checked);
}

(六) “序列设置”分组框功能

1 棒柱样式 ComboBox

void mainwindow::on_cBoxBarStyle_currentIndexChanged(int index)
{QAbstract3DSeries::Mesh aMesh;aMesh = QAbstract3DSeries::Mesh(index + 1);  //0=MeshUserDefinedseries->setMesh(aMesh);
}

1-1 棒柱形状

enum QAbstract3DSeries::Mesh
并非所有样式都可用于所有可视化类型。

常量注释
QAbstract3DSeries::MeshUserDefined0用户定义网格,通过QAbstract3DSeries::userDefinedMesh属性设置
QAbstract3DSeries::MeshBar1基本矩形条
QAbstract3DSeries::MeshCube2基本多维数据集
QAbstract3DSeries::MeshPyramid3四边形金字塔
QAbstract3DSeries::MeshCone4基本圆锥体
QAbstract3DSeries::MeshCylinder5基本气缸
QAbstract3DSeries::MeshBevelBar6略微倾斜(圆形)的矩形钢筋
QAbstract3DSeries::MeshBevelCube7略微倾斜(圆形)的立方体
QAbstract3DSeries::MeshSphere8球体
QAbstract3DSeries::MeshMinimal9最小的三维网格:一个三角锥
QAbstract3DSeries::MeshArrow10向上的箭头
QAbstract3DSeries::MeshPoint112D点

2 光滑效果 CheckBox

void mainwindow::on_chkBoxSmooth_clicked(bool checked)
{series->setMeshSmooth(checked);
}

3 显示选中棒柱的标签 CheckBox

void mainwindow::on_chkBoxItemLabel_clicked(bool checked)
{series->setItemLabelFormat("value at (@rowLabel,@colLabel): %.1f");series->setItemLabelVisible(checked);
}

(七) 有关QBarDataProxy数据管理接口

函数功能
int addRow()添加一行数据,一行数据是 QBarDataRow 类型对象
void insertRow()在某行之前插入一行数据
void removeRows()从某行开始,移除指定行数的数据
void setRow ()为某一行重新设置一行数据
QBarDataRow *rowAt()返回某一行的数据
void setItem()根据行号和列号,设置某个棒柱数据项
QBarDataltem *itemAt()根据行号和列号,返回单个棒柱数据项
void resetArray()若不带任何参数,就清除数据代理所有的数据和标签;若使用一个 QBarDataArray类型的对象作为输入参数,就重新设置棒柱数据数组
int rowCount()返回数据代理的行数
void setRowLabels()用一个字符串列表设置行坐标轴的标签
StringList rowLabels()返回行坐标轴的所有标签
void setColumnLabels()用一个字符串列表设置列坐标轴的标签
QStringList columnLabels()返回列坐标轴的所有标签

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战案例!风控实战催收评分卡(附 Python 源码)

在风控环节中&#xff0c;传统观念A卡为主、B卡C卡为辅&#xff0c;但是在市场逐步饱和、政策利率要求越来越低的背景下&#xff0c;B卡和C卡也越来越重要。 本文以简易贷后数据实战催收评分模型&#xff0c;预测在用户逾期后、未来能否催回。 一、数据读取 数据来源某比赛网…

低压 5V 全桥驱动芯片GC9114 ,适用于摄像机、消费类等产品上

GC9114 是一款低压 5V 全桥驱动芯片&#xff0c;为摄像机、消费类产品、玩具和其他低压或者电池供电的运动控制类应用提供了集成的电机驱动解决方案。 GC9114 能提供高达 1.3A 的持续输出电流。可以工作在 2~6V 的电源电压上。具有 PWM&#xff08;IN/IN&#xff09;输入接口,与…

一文详解VScode 的远程开发

VS code登录服务器后进行编码和调试&#xff0c;VS code上的所有功能都可以使用&#xff0c;和在本地开发基本无区别。 一、配置免密远程登录 因为是要远程登录&#xff0c;那么需要通过使用ssh进行密钥对登录&#xff0c;这样每次登录服务器就可以不用输入密码了。 先来一句官…

docsify 文章加密

docsify 文章加密 什么是docsify&#xff1f; 简单来说是一款便捷的文档网站 官网文档 docsify支持很多中部署方式&#xff0c;包括单独部署&#xff0c;Github部署&#xff0c;Gitee部署....对于没有前端能力固定样式非常友好 加密需求 对于部署上的文档在部分时候需要进…

OV5640 摄像头的图像平滑处理

如图所示&#xff0c;这是整个视频采集系统的原理框图。 上电初始&#xff0c;FPGA 需要通过 IIC 接口对 CMOS Sensor 进行寄存器初始化配置。这些初始化的基本参数&#xff0c;即初始化地址对应的初始化数据都存储在一个预先配置好的 FPGA 片内 ROM中。在初始化配置完成后&…

过去半年信竞基础学习总结

当Richard同学从去年7月份&#xff0c;开始从YY班学习C和信息学竞赛时&#xff0c;他对C还一无所知&#xff0c;但对计算机和编程的兴趣让他一直都乐在其中。在过去的半年中&#xff0c;通过参加各个平台的月赛&#xff0c;让他更加热爱编程&#xff0c;也让Richard更加了解自己…

中国建设银行 关于解决微软升级导致插入网银盾无法自动打开企业网银的通知

关于解决微软升级导致插入网银盾无法自动打开企业网银的通知 发布时间&#xff1a;2023-10-18 尊敬的客户&#xff1a; 近期Windows操作系统升级会禁止使用IE浏览器&#xff0c;可能会导致您在插入网银盾后无法自动弹出企业网银登录页面&#xff0c;您可以通过以下方式解决&…

MODBUS转PROFINET网关与全数字交流伺服配置案例

MODBUS转PROFINET网关连接与全数字交流伺服驱动系统的配置案例&#xff0c;这一通信方式极大地简化了工业自动化系统中的数据传输和控制过程。变频器和伺服电机可以实现数据交流和控制指令的实时传输&#xff0c;从而实现更精确更高效的生产过程。 案例简介&#xff1a;本案例是…

NODE笔记 0

一些简单的node学习笔记记录&#xff0c;是Vue等前端框架的基础 入门学习备忘录 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 node.js 内置网络服务器&#xff0c;是前端框架学习的基础&#xff1a; 概念&#xff1a;…

【python爬虫开发实战 情感分析】利用爬虫爬取城市评论并对其进行情感分析

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a; python网络爬虫从基础到实战 带你学习爬虫从基础到实战 深度学习带你感受AI的魅力 &#x1f4a1;往期推荐&#xff1a; ⭐️前面比较重要的基础内容&#xff1a; 【Py…

安全远控如何设置?揭秘ToDesk、TeamViewer 、向日葵安全远程防御大招

写在前面一、远程控制&#xff1a;安全性不可忽略二、远控软件安全设置实测 ◉ ToDesk◉ TeamViewer◉ 向日葵 三、远控安全的亮点功能四、个人总结与建议 写在前面 说到远程办公&#xff0c;相信大家都不陌生。远程工作是员工在家中或者其他非办公场所上班的一种工作模式&am…

「PyMuPDF 专栏 」PyMuPDF创建PDF、拆分PDF

文章目录 一、本章前言二、使用PyMuPDF创建PDF文档1、实例代码2、过程详解①. 安装PyMuPDF②. 导入PyMuPDF模块③. 创建一个新的PDF文档④. 添加页面和内容⑤. 保存文档 三、使用PyMuPDF拆分PDF文档1、实例代码2、过程解析①. 导入模块②. 定义函数③. 打开源PDF文件④. 遍历页…