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

这篇具有很好参考价值的文章主要介绍了Qt 三维柱状图 Q3DBar 和 三维条形图中的数据序列 QBar3DSeries。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

效果图:
Qt 三维柱状图 Q3DBar 和 三维条形图中的数据序列 QBar3DSeries,Qt笔记,qt,3d,开发语言

(二) 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继承自QWindow
    graph3D->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=MeshUserDefined
    series->setMesh(aMesh);
}

1-1 棒柱形状

enum QAbstract3DSeries::Mesh
并非所有样式都可用于所有可视化类型。文章来源地址https://www.toymoban.com/news/detail-788127.html

常量 注释
QAbstract3DSeries::MeshUserDefined 0 用户定义网格,通过QAbstract3DSeries::userDefinedMesh属性设置
QAbstract3DSeries::MeshBar 1 基本矩形条
QAbstract3DSeries::MeshCube 2 基本多维数据集
QAbstract3DSeries::MeshPyramid 3 四边形金字塔
QAbstract3DSeries::MeshCone 4 基本圆锥体
QAbstract3DSeries::MeshCylinder 5 基本气缸
QAbstract3DSeries::MeshBevelBar 6 略微倾斜(圆形)的矩形钢筋
QAbstract3DSeries::MeshBevelCube 7 略微倾斜(圆形)的立方体
QAbstract3DSeries::MeshSphere 8 球体
QAbstract3DSeries::MeshMinimal 9 最小的三维网格:一个三角锥
QAbstract3DSeries::MeshArrow 10 向上的箭头
QAbstract3DSeries::MeshPoint 11 2D点

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() 返回列坐标轴的所有标签

到了这里,关于Qt 三维柱状图 Q3DBar 和 三维条形图中的数据序列 QBar3DSeries的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Python数据可视化】matplotlib之绘制常用图形:折线图、柱状图(条形图)、饼图和直方图

    文章传送门 Python 数据可视化 matplotlib之绘制常用图形:折线图、柱状图(条形图)、饼图和直方图 matplotlib之设置坐标:添加坐标轴名字、设置坐标范围、设置主次刻度、坐标轴文字旋转并标出坐标值 matplotlib之增加图形内容:设置图例、设置中文标题、设置网格效果 matplo

    2024年01月16日
    浏览(56)
  • ● 84.柱状图中最大的矩形

     84.柱状图中最大的矩形

    2024年02月11日
    浏览(41)
  • LeetCode 84. 柱状图中最大的矩形

    84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入: heights = [2,1,5,6,2,3] 输出: 10 解释: 最大的矩形为图中红色区域,面积为 10 示例 2: 输入

    2024年02月03日
    浏览(32)
  • (力扣记录)84. 柱状图中最大的矩形

    数据结构类型: 栈 时间复杂度: O(N) 空间复杂度: O(N) 代码实现:

    2024年01月20日
    浏览(36)
  • Python——柱状图(条形图、堆叠图)

    目录 1 基本函数 2 竖条形图 3 横条形图 4 并列条形图 5 添加标签 6 堆叠柱形图 x:数据标签(横坐标); height:个数或一个数组,条形的高度; [width]:可选参数,一个数或一个数组,条形的宽度,默认为 0.8

    2024年02月13日
    浏览(39)
  • 【算法练习Day51】柱状图中最大的矩形

    ​📝个人主页:@Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯 长路漫漫浩浩,万事皆有期待 力扣题目链接 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩

    2024年01月22日
    浏览(42)
  • OJ练习第101题——柱状图中最大的矩形

    力扣链接:84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 我们先嵌套一层 while 循环来向左找到第一个比柱体 i 高度小的柱体,这个过程是 O(N) 的; 单调

    2024年02月04日
    浏览(34)
  • 算法修炼Day60|● 84.柱状图中最大的矩形

     LeetCode:84.柱状图中最大的矩形 84. 柱状图中最大的矩形 - 力扣(LeetCode) 1.思路 双指针思路,以当前数组为中心,借助两个数组存放当前数柱左右两侧小于当前数柱高度的索引,进行h*w的计算。注意首尾节点的左侧索引和右侧索引需要单独声名为0. 单调栈,在原数组的基础上

    2024年02月11日
    浏览(41)
  • 算法刷题Day 60 柱状图中的最大矩阵

    暴力解法 超时了 分别找出当前位置左边 第一个 比自己小的索引(的后一个位置)和右边 第一个 比自己小的索引(的前一个位置),这个范围之内,就是以当前位置的高度所能达到的最大宽度。 单调栈 有了接雨水那道题的经验,这一道题可以模仿着做出了

    2024年02月14日
    浏览(54)
  • 【力扣】84. 柱状图中最大的矩形 <模拟、双指针、单调栈>

    给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10 示例 2: 输入: heights = [2,4] 输出: 4 提示

    2024年02月12日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包