Qt之QtDataVisualization各三维图表的简单使用(含源码+注释)

一、图表操作示例图

1.图表选择示例

下图演示了通过下拉列表框切换三维图表的操作。
在这里插入图片描述

2.视角选项操作

下图演示了自动切换、通过spinBox控件切换和slider控件的缩放功能(三维图表自带有鼠标滚轮缩放功能)。
在这里插入图片描述

3.样式选项操作

下图演示了主题奇幻,系列样式切换,选择模式切换的效果
在这里插入图片描述

4.其他选项操作

下图演示了显示背景、显示网格、显示倒影和二维显示等功能。
在这里插入图片描述
二维显示截图
在这里插入图片描述

提示:不会使用Qt设计师设计界面的小伙伴点击这里

二、QtDataVisualization(个人理解)

  1. 使用前需要在pro文件中添加“QT += datavisualization”;
  2. 和QChart类似,导入头文件后还需通过“using namespace QtDataVisualization;”代码使用对应的命名空间;
  3. 其数据的存储方式也和QChart来说大同小异,有分装格式的,如:QWidget->Graph->Series->Proxy,QWidget为通过createWindowContainer()函数返回的容器对象,其中包含对应的图形对象(Graphi),三维图形也包括系列对象(series),并且系列对象中包含数据代理(Proxy,用于数据管理等),数据代理中也包括不同的数据对象,记住这个顺序,大体也是没问题的。

三、自定义槽函数的添加(UI界面)

在QChart文章中涉及到了槽函数添加的几种方式,现在再演示一种,操作流程如下:

  1. 按F4键,进入信号槽编辑模式;
  2. 选中按钮拖动会出现红色的关联线(需要连接哪个控件只需将关联线拖到到对应的控件上即可,本文为连接this,所以拖到了外边);
  3. 弹出配置连接后,选择信号,点击槽函数下方的编辑按钮,在信号槽界面添加自定义槽函数,然后确定,则成功绑定信号槽。
    在这里插入图片描述
    本文中和QChart一样也包含动态属性、按钮组,在此就不再介绍,想要了解的小伙伴点击这里QChart图表的简单使用,在该文的“部分源码讲解”内容中。

四、源码

(因为本文ui中包含动态属性,所以本文会留下ui代码,可复制粘贴到ui文件使用)

CMainWindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include <QMainWindow>
#include <QAbstractButton>

// 导入数据可视化头文件
#include <QtDataVisualization>
//! 和QChart一样是要使用对应的命名空间
using namespace QtDataVisualization;

namespace Ui {
class CMainWindow;
}
//! 设置一个模板函数
template<class T>
void setSeriesStyle(T graphi, int index);

class CMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit CMainWindow(QWidget *parent = nullptr);
    ~CMainWindow();

    /**
     * @brief create3DBarGraph 创建三维柱状图
     * @return 返回三维柱状图指针
     */
    QAbstract3DGraph * create3DBarGraph();

    /**
     * @brief create3DScatterGraph 创建三维散点图
     * @return 返回散点图指针
     */
    QAbstract3DGraph * create3DScatterGraph();

    /**
     * @brief create3DSurfaceGraph 创建三维曲面图
     * @return 返回三维曲面图指针
     */
    QAbstract3DGraph * create3DSurfaceGraph();

    /**
     * @brief createValue3DAxis 创建值坐标轴
     * @param axisTitle 坐标轴标题
     * @param titleVisible 是否显示标题
     * @param min 坐标轴最小值
     * @param max 坐标轴最大值
     * @return 返回值坐标轴指针
     */
    QValue3DAxis *createValue3DAxis(QString axisTitle, bool titleVisible = true, float min = 0, float max = 100);

    /**
     * @brief createCategory3DAxis 创建文本坐标轴
     * @param axisTitle 坐标轴标题
     * @param titleVisible 是否显示坐标轴
     * @param labList 坐标轴标签
     * @return 返回值坐标轴指针
     */
    QCategory3DAxis *createCategory3DAxis(QString axisTitle, bool titleVisible = true, QStringList labList = QStringList());

    // QObject interface
protected:
    /**
     * @brief timerEvent 定时器时间
     * @param event 定时器对象
     */
    void timerEvent(QTimerEvent *event);

private slots:
    /**
     * @brief on_angleValueChange 视角改变槽函数
     * @param val 角度值
     */
    void on_angleValueChange(int val);

    /**
     * @brief on_otherOptionGroup_buttonClicked 其他选项按钮组槽函数
     * @param button 点击的按钮指针
     */
    void on_otherOptionGroup_buttonClicked(QAbstractButton *button);

    /**
     * @brief on_seriesStyleComboBox_currentIndexChanged 系列样式设置槽函数
     * @param index 样式索引值
     */
    void on_seriesStyleComboBox_currentIndexChanged(int index);

    /**
     * @brief on_themeComboBox_currentIndexChanged 主题选择槽函数
     * @param index 主题索引值
     */
    void on_themeComboBox_currentIndexChanged(int index);

    /**
     * @brief on_selectModeComboBox_currentIndexChanged 选择模式槽函数
     * @param index 选择模式索引值
     */
    void on_selectModeComboBox_currentIndexChanged(int index);

    /**
     * @brief on_scaleSlider_sliderMoved 缩放功能槽函数
     * @param position 缩放值
     */
    void on_scaleSlider_sliderMoved(int position);

    /**
     * @brief on_autoSwitchAngleBtn_clicked 自动切换视角按钮槽函数
     * @param checked 按钮选中状态
     */
    void on_autoSwitchAngleBtn_clicked(bool checked);

    /**
     * @brief on_typeComboBox_currentIndexChanged 图表类型选选择槽函数
     * @param index 类型索引值
     */
    void on_typeComboBox_currentIndexChanged(int index);

private:
    Ui::CMainWindow             *ui;            // ui对象指针

    QList<QAbstract3DGraph *>   m_graphLsit;    // 图表容器指针

    int                         m_timer;        // 定时器对象

};

#endif // CMAINWINDOW_H

CMainWindow.cpp

#include "CMainWindow.h"
#include "ui_CMainWindow.h"
#include <QtDebug>

CMainWindow::CMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);
    // 设置标题
    this->setWindowTitle("三维图形的简单使用");

    // 创建三维柱状图
    m_graphLsit.append(create3DBarGraph());
    // 创建三维散点图
    m_graphLsit.append(create3DScatterGraph());
    // 创建三维曲面图
    m_graphLsit.append(create3DSurfaceGraph());

    // 重置随机数种子
    srand(QDateTime::currentSecsSinceEpoch() % 1000000);

//    ui->otherOptionGroup->setExclusive(false);  // 设置按钮组可多选(ui界面已设置)
}

CMainWindow::~CMainWindow()
{
    // 遍历删除图表对象
    for(int index = m_graphLsit.count() - 1; index != -1; --index)
    {
        // 释放图表
        delete m_graphLsit.at(index);
    }
    // 删除ui对象
    delete ui;
}

QAbstract3DGraph *CMainWindow::create3DBarGraph()
{
    // 创建三维柱状图对象
    Q3DBars *bars = new Q3DBars;
    // 创建三维柱状图容器
    QWidget *container = QWidget::createWindowContainer(bars);
    // 将当前容器添加到栈窗口对象中,并设置容器为栈窗口当前窗口
    ui->stackedWidget->addWidget(container);
    ui->stackedWidget->setCurrentWidget(container);


    // 创建三维柱状图坐标轴对象
    bars->setValueAxis(createValue3DAxis("Value Axis", true, 0, 10));
    // 创建坐标轴标签容器并添加到坐标轴中
    // 列坐标轴
    QStringList colLabs;
    colLabs << "Column1" << "Column2" << "Column3";
    bars->setColumnAxis(createCategory3DAxis("Column Category Axis", true, colLabs));
    // 行坐标轴
    QStringList rowLabs;
    rowLabs << "Row1" << "Row2" << "Row3";
    bars->setRowAxis(createCategory3DAxis("Row Category Axis", true, rowLabs));


    // 创建三维柱状图系列对象
    QBar3DSeries *series = new QBar3DSeries;
    // 将系列对象添加到三维柱状图对象中
    bars->addSeries(series);

    // 创建三维柱状图数据容器
    QBarDataArray *array = new QBarDataArray;
    // 循环创建数据
    for(int index = 0; index != 3; ++index)
    {
        // 创建柱状图行数据容器
        QBarDataRow *dataRow = new QBarDataRow;
        // 使用随机数添加数据
        *dataRow << rand() % 10 << rand() % 10 << rand() % 10 << rand() % 10 << rand() % 10;
        // 将行数据添加到array对象中
        array->append(dataRow);
    }
    // 将创建的数据添加到系列对象中(当指针容器指针不同时,将重置添加)
    series->dataProxy()->resetArray(array);

    // 设置动态属性(类型,作用为在设置系列样式槽函数中区分)
    bars->setProperty("Type", 0);

    // 返回三维柱状图对象
    return bars;
}

QAbstract3DGraph *CMainWindow::create3DScatterGraph()
{
    // 创建三维散点图对象
    Q3DScatter *scatter = new Q3DScatter;
    // 创建三维散点图容器
    QWidget *container = QWidget::createWindowContainer(scatter);
    // 将当前容器添加到栈窗口对象中
    ui->stackedWidget->addWidget(container);

    //! 创建三维散点图的坐标轴
    //! 因为是三维散点图,所以包括X、Y、Z三个方向的坐标轴(并且三个坐标轴类型都为值坐标轴哦)
    // 创建X、Y、Z轴并添加
    scatter->setAxisX(createValue3DAxis("X Axis"));
    scatter->setAxisY(createValue3DAxis("Y Axis"));
    scatter->setAxisZ(createValue3DAxis("Z Axis"));


    // 创建三维散点图的系列对象
    QScatter3DSeries *series = new QScatter3DSeries;
    // 将系列对象添加到三维散点图对象中
    scatter->addSeries(series);

    // 创建三维散点图的数据容器
    QScatterDataArray array;
    // 循环添加数据
    for(int index = 0; index != 30; ++index)
    {
        // 使用随机数添加点
        array.append(QVector3D(rand() % 100, rand() % 100, rand() % 100));
    }
    // 将创建的数据添加到系列对象中(做追加数组的操作)
    series->dataProxy()->addItems(array);

    // 设置动态属性(类型,作用为在设置系列样式槽函数中区分)
    scatter->setProperty("Type", 1);

    // 返回三维散点图指针
    return scatter;
}

QAbstract3DGraph *CMainWindow::create3DSurfaceGraph()
{
    // 创建三维曲面图对象
    Q3DSurface *surface = new Q3DSurface;
    // 创建三维曲面图容器
    QWidget *container = QWidget::createWindowContainer(surface);
    // 将容器添加到栈窗口中
    ui->stackedWidget->addWidget(container);


    //! 创建三维散点图的坐标轴
    //! 因为是三维散点图,所以包括X、Y、Z三个方向的坐标轴(并且三个坐标轴类型都为值坐标轴哦)
    // 创建X、Y、Z轴并添加
    surface->setAxisX(createValue3DAxis("X Axis"));
    surface->setAxisY(createValue3DAxis("Y Axis"));
    surface->setAxisZ(createValue3DAxis("Z Axis"));


    // 创建三维曲面图系列对象
    QSurface3DSeries *series = new QSurface3DSeries;
    // 将系列添加到三维曲面图中
    surface->addSeries(series);

    // 创建三维曲面图数据容器
    QSurfaceDataArray *array = new QSurfaceDataArray;
    // 创建三维曲面图数据
    for(int index = 0; index != 5; ++index)
    {
        // 创建三维曲面图行数据容器
        QSurfaceDataRow *dataRow = new QSurfaceDataRow;
        // 遍历添加数据到行容器
        for(int valIdx = 0; valIdx != 3; ++valIdx)
        {
            // 随机数添加数据
            dataRow->append(QVector3D(rand() % 100, rand() % 100, rand() % 100));
        }
        // 将行容器添加到array中
        array->append(dataRow);
    }
    // 将数据添加到系列对象中
    series->dataProxy()->resetArray(array);

    //! 因为曲面图是面,所以切换系列类型没有变化
    //! 若要设置面的样式可像下方一样调用setDrawMode函数
    //! surface->seriesList()[0]->setDrawMode(QSurface3DSeries::DrawFlag(vlaue));
    //! value:枚举值 其中枚举值如下
    //! QSurface3DSeries::DrawWireframe 仅绘制网格。
    //! QSurface3DSeries::DrawSurface   仅绘制曲面。
    //! QSurface3DSeries::DrawSurfaceAndWireframe    绘制曲面和栅格。

    //! 设置动态属性(类型,作用为在设置系列样式槽函数中区分)
    surface->setProperty("Type", -1);


    // 返回三维曲面图对象
    return surface;

}

QValue3DAxis *CMainWindow::createValue3DAxis(QString axisTitle, bool titleVisible, float min, float max)
{
    // 创建值坐标轴对象
    QValue3DAxis *axis = new QValue3DAxis;
    axis->setTitle(axisTitle);  // 设置坐标轴标题
    axis->setTitleVisible(titleVisible); // 设置标题是否显示
    axis->setRange(min, max);   // 设置坐标轴取值范围
    // 返回坐标轴对象
    return axis;
}

QCategory3DAxis *CMainWindow::createCategory3DAxis(QString axisTitle, bool titleVisible, QStringList labList)
{
    // 创建文本坐标轴对象
    QCategory3DAxis *axis = new QCategory3DAxis;
    axis->setTitle(axisTitle);  // 设置坐标轴标题
    axis->setTitleVisible(titleVisible); // 设置标题是否显示
    axis->setLabels(labList);   // 设置坐标轴标签
    // 返回坐标轴对象
    return axis;

}

void CMainWindow::on_angleValueChange(int val)
{
    // 拿到信号发送者
    QSpinBox *spinBox = dynamic_cast<QSpinBox *>(sender());

    // 若当前为定时改变视角则不设置活动摄像角度,并将动态属性值设置为false
    if(spinBox->property("RotationFlag").toBool())
    {
        spinBox->setProperty("RotationFlag", false);
        return;
    }

    // 拿到视角类型
    int type = spinBox->property("DirectionType").toInt();

    // 判断当前方向类型,并将角度赋到对应位置
    if(0 == type)
    {
        // 遍历设置所有三维图的X轴视角
        foreach(QAbstract3DGraph *graph, m_graphLsit)
        {
            // 获取图表的视图->活动摄像头->设置角度
            graph->scene()->activeCamera()->setXRotation(val);
        }
    }
    else if(1 == type)
    {
        // 遍历设置所有三维图的Y轴视角
        foreach(QAbstract3DGraph *graph, m_graphLsit)
        {
            // 获取图表的视图->活动摄像头->设置角度
            graph->scene()->activeCamera()->setYRotation(val);
        }
    }

}

void CMainWindow::on_otherOptionGroup_buttonClicked(QAbstractButton *button)
{
    // 将按钮对象转为复选框对象
    QCheckBox *curBox = dynamic_cast<QCheckBox *>(button);
    // 获取当前按钮的类型
    int type = curBox->property("OptionType").toInt();
    // 获取按钮选择状态
    bool checkedStatus = curBox->isChecked();
    switch (type)
    {
    case 0:
    {
        // 循环设置图表状态
        foreach(QAbstract3DGraph *graph, m_graphLsit)
        {
            // 设置背景可用
            graph->activeTheme()->setBackgroundEnabled(checkedStatus);
            // 标签可用
            graph->activeTheme()->setLabelBackgroundEnabled(checkedStatus);
        }
        break;
    }
    case 1:
    {
        // 循环设置图表状态
        foreach(QAbstract3DGraph *graph, m_graphLsit)
        {
            // 设置显示网格
            graph->activeTheme()->setGridEnabled(checkedStatus);
        }
        break;
    }
    case 2:
    {
        // 循环设置图表状态
        foreach(QAbstract3DGraph *graph, m_graphLsit)
        {
            // 设置显示倒影
            graph->setReflection(checkedStatus);
        }
        break;
    }
    case 3:
    {
        // 循环设置图表状态
        foreach(QAbstract3DGraph *graph, m_graphLsit)
        {
            // 设置正交投影显示(偏二维)
            graph->setOrthoProjection(checkedStatus);
        }
        break;
    }
    default:
        break;
    }
}

void CMainWindow::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);
    // 创建当前摄像头对象
    Q3DCamera *curCamera;
    // 循环设置相机视角
    foreach(QAbstract3DGraph *graph, m_graphLsit)
    {
        // 获取当前视图视角
        curCamera = graph->scene()->activeCamera();
        // 获取当前视角值
        int curCameraPreset = curCamera->cameraPreset();
        // 判断获取下一是视角值
        int cameraPreset = curCameraPreset == 21? 1: curCameraPreset + 1;
        // 设置相机视角
        curCamera->setCameraPreset(Q3DCamera::CameraPreset(cameraPreset));
    }

    // 设置水平视角控件值
    ui->horAngleSpinBox->setValue(curCamera->xRotation());
    // 设置水平动态属性
    ui->horAngleSpinBox->setProperty("RotationFlag", true);
    // 设置垂直视角控件值
    ui->verAngleSpinBox->setValue(curCamera->yRotation());
    // 设置水平动态属性
    ui->verAngleSpinBox->setProperty("RotationFlag", true);
}

void CMainWindow::on_seriesStyleComboBox_currentIndexChanged(int index)
{
    // 循环设置图表系列状态
    foreach(QAbstract3DGraph *graph, m_graphLsit)
    {
        int type = graph->property("Type").toInt();
        // 获取当前图表类型
        switch (type)
        {
        case 0:
        {
            // 调用样式模板函数
            setSeriesStyle(dynamic_cast<Q3DBars *>(graph), index);
            break;
        }
        case 1:
        {
            // 调用样式模板函数
            setSeriesStyle(dynamic_cast<Q3DScatter *>(graph), index);
            break;
        }
        default:
            break;
        }
    }
}

void CMainWindow::on_themeComboBox_currentIndexChanged(int index)
{
    // 循环设置图表主题
    foreach(QAbstract3DGraph *graph, m_graphLsit)
    {
        graph->activeTheme()->setType(Q3DTheme::Theme(index));
    }
}

void CMainWindow::on_selectModeComboBox_currentIndexChanged(int index)
{
    // 设置柱状图的选择模式
    m_graphLsit.first()->setSelectionMode(QAbstract3DGraph::SelectionFlag(index));
}

void CMainWindow::on_scaleSlider_sliderMoved(int position)
{
    // 循环设置图表缩放
    foreach(QAbstract3DGraph *graph, m_graphLsit)
    {
        graph->scene()->activeCamera()->setZoomLevel(position);
    }
}

void CMainWindow::on_autoSwitchAngleBtn_clicked(bool checked)
{
    // 根据状态做出相应操作
    if(checked)
    {
        // 改变按钮文本
        ui->autoSwitchAngleBtn->setText("停止");
        // 启动定时器
        m_timer = startTimer(750);
    }
    else
    {
        // 改变按钮文本
        ui->autoSwitchAngleBtn->setText("开始");
        // 终止定时器
        killTimer(m_timer);
    }
}

template<class T>
void setSeriesStyle(T graphi, int index)
{
    // 循环设置图表样式
    foreach(QAbstract3DSeries *series, graphi->seriesList())
    {
        //! 设置样式
        //! 索引值加1是防止设置值为0的Mesh,未作出对应操作设置该值的样式会导致程序崩溃
        //! 帮助中这样形容(翻译):用户定义网格,通过QAbstract3DSeries::userDefinedMesh属性设置。
        series->setMesh(QAbstract3DSeries::Mesh(index + 1));
    }
}

void CMainWindow::on_typeComboBox_currentIndexChanged(int index)
{
    // 设置当前显示的图表
    ui->stackedWidget->setCurrentIndex(index);

    //! 判断选择模式禁用,仅在三维柱状图下可用
    //! 因为在测试时发现本文中的三维散点图仅支持“无”和单项选择模式,三维曲面图不支持选择模式
    ui->selectModeComboBox->setEnabled(0 == index);

    //! 判断显示倒影禁用,仅在三维柱状图下可用
    //! 因为在测试时发现本文中的三维散点图、三维曲面图并无倒影显示
    ui->showReflectionCheckBox->setEnabled(0 == index);

    //! 判断设置系列样式禁用
    //! 三维曲面图设置Mesh无效,则禁用
    ui->seriesStyleComboBox->setEnabled(2 != index);

}

CMainWindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>CMainWindow</class>
 <widget class="QMainWindow" name="CMainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>720</width>
    <height>466</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>CMainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1">
    <property name="spacing">
     <number>0</number>
    </property>
    <property name="leftMargin">
     <number>0</number>
    </property>
    <property name="topMargin">
     <number>0</number>
    </property>
    <property name="rightMargin">
     <number>0</number>
    </property>
    <property name="bottomMargin">
     <number>0</number>
    </property>
    <item>
     <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1,1,1">
      <property name="spacing">
       <number>10</number>
      </property>
      <property name="leftMargin">
       <number>7</number>
      </property>
      <property name="topMargin">
       <number>5</number>
      </property>
      <property name="rightMargin">
       <number>10</number>
      </property>
      <property name="bottomMargin">
       <number>5</number>
      </property>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_2">
        <property name="leftMargin">
         <number>5</number>
        </property>
        <property name="topMargin">
         <number>5</number>
        </property>
        <property name="rightMargin">
         <number>5</number>
        </property>
        <property name="bottomMargin">
         <number>5</number>
        </property>
        <item>
         <widget class="QLabel" name="label">
          <property name="text">
           <string>三维(图)类型:</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="typeComboBox">
          <item>
           <property name="text">
            <string>三维柱状图</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>三维散点图</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>三维曲面图</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <widget class="QGroupBox" name="groupBox">
        <property name="title">
         <string>视角选项</string>
        </property>
        <layout class="QGridLayout" name="gridLayout">
         <property name="leftMargin">
          <number>5</number>
         </property>
         <property name="topMargin">
          <number>5</number>
         </property>
         <property name="rightMargin">
          <number>5</number>
         </property>
         <property name="bottomMargin">
          <number>5</number>
         </property>
         <property name="verticalSpacing">
          <number>5</number>
         </property>
         <item row="0" column="0">
          <widget class="QLabel" name="label_2">
           <property name="text">
            <string>自动切换视角:</string>
           </property>
          </widget>
         </item>
         <item row="0" column="1">
          <widget class="QPushButton" name="autoSwitchAngleBtn">
           <property name="maximumSize">
            <size>
             <width>100</width>
             <height>16777215</height>
            </size>
           </property>
           <property name="text">
            <string>开始</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
           </property>
          </widget>
         </item>
         <item row="1" column="0" colspan="2">
          <layout class="QHBoxLayout" name="horizontalLayout">
           <property name="spacing">
            <number>0</number>
           </property>
           <item>
            <widget class="QLabel" name="label_3">
             <property name="text">
              <string>水平视角:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QSpinBox" name="horAngleSpinBox">
             <property name="suffix">
              <string>°</string>
             </property>
             <property name="prefix">
              <string/>
             </property>
             <property name="minimum">
              <number>-180</number>
             </property>
             <property name="maximum">
              <number>180</number>
             </property>
             <property name="singleStep">
              <number>5</number>
             </property>
             <property name="DirectionType" stdset="0">
              <number>0</number>
             </property>
            </widget>
           </item>
           <item>
            <spacer name="horizontalSpacer">
             <property name="orientation">
              <enum>Qt::Horizontal</enum>
             </property>
             <property name="sizeHint" stdset="0">
              <size>
               <width>40</width>
               <height>20</height>
              </size>
             </property>
            </spacer>
           </item>
           <item>
            <widget class="QLabel" name="label_4">
             <property name="text">
              <string>垂直视角:</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QSpinBox" name="verAngleSpinBox">
             <property name="suffix">
              <string>°</string>
             </property>
             <property name="prefix">
              <string/>
             </property>
             <property name="maximum">
              <number>90</number>
             </property>
             <property name="singleStep">
              <number>5</number>
             </property>
             <property name="DirectionType" stdset="0">
              <number>1</number>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item row="2" column="0">
          <widget class="QLabel" name="label_5">
           <property name="text">
            <string>缩放:</string>
           </property>
          </widget>
         </item>
         <item row="2" column="1">
          <widget class="QSlider" name="scaleSlider">
           <property name="minimum">
            <number>10</number>
           </property>
           <property name="maximum">
            <number>500</number>
           </property>
           <property name="value">
            <number>100</number>
           </property>
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
      </item>
      <item>
       <widget class="QGroupBox" name="groupBox_2">
        <property name="title">
         <string>样式选项</string>
        </property>
        <layout class="QFormLayout" name="formLayout">
         <property name="horizontalSpacing">
          <number>0</number>
         </property>
         <property name="verticalSpacing">
          <number>10</number>
         </property>
         <property name="leftMargin">
          <number>5</number>
         </property>
         <property name="topMargin">
          <number>5</number>
         </property>
         <property name="rightMargin">
          <number>5</number>
         </property>
         <property name="bottomMargin">
          <number>5</number>
         </property>
         <item row="0" column="0">
          <widget class="QLabel" name="label_6">
           <property name="text">
            <string>主题:</string>
           </property>
          </widget>
         </item>
         <item row="0" column="1">
          <widget class="QComboBox" name="themeComboBox">
           <item>
            <property name="text">
             <string>ThemeQt</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemePrimaryColors</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeDigia</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeStoneMoss</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeArmyBlue</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeRetro</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeEbony</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeIsabelle</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>ThemeUserDefined</string>
            </property>
           </item>
          </widget>
         </item>
         <item row="1" column="0">
          <widget class="QLabel" name="label_7">
           <property name="text">
            <string>系列样式:</string>
           </property>
          </widget>
         </item>
         <item row="1" column="1">
          <widget class="QComboBox" name="seriesStyleComboBox">
           <item>
            <property name="text">
             <string>MeshBar</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshCube</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshPyramid</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshCone</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshCylinder</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshBevelBar</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshBevelCube</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshSphere</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshMinimal</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshArrow</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>MeshPoint</string>
            </property>
           </item>
          </widget>
         </item>
         <item row="2" column="0">
          <widget class="QLabel" name="label_8">
           <property name="text">
            <string>选择模式:</string>
           </property>
          </widget>
         </item>
         <item row="2" column="1">
          <widget class="QComboBox" name="selectModeComboBox">
           <item>
            <property name="text">
             <string>SelectionNone</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionItem</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionRow</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionItemAndRow</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionColumn</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionItemAndColumn</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionRowAndColumn</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionItemRowAndColumn</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionSlice</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>SelectionMultiSeries</string>
            </property>
           </item>
          </widget>
         </item>
        </layout>
       </widget>
      </item>
      <item>
       <widget class="QGroupBox" name="groupBox_3">
        <property name="title">
         <string>其他选项</string>
        </property>
        <layout class="QGridLayout" name="gridLayout_3">
         <property name="leftMargin">
          <number>5</number>
         </property>
         <property name="topMargin">
          <number>5</number>
         </property>
         <property name="rightMargin">
          <number>5</number>
         </property>
         <property name="bottomMargin">
          <number>5</number>
         </property>
         <property name="spacing">
          <number>0</number>
         </property>
         <item row="0" column="0">
          <widget class="QCheckBox" name="showBgCheckBox">
           <property name="text">
            <string>显示背景</string>
           </property>
           <property name="checked">
            <bool>true</bool>
           </property>
           <property name="OptionType" stdset="0">
            <number>0</number>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">otherOptionGroup</string>
           </attribute>
          </widget>
         </item>
         <item row="0" column="1">
          <widget class="QCheckBox" name="showGridCheckBox">
           <property name="text">
            <string>显示网格</string>
           </property>
           <property name="checked">
            <bool>true</bool>
           </property>
           <property name="OptionType" stdset="0">
            <number>1</number>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">otherOptionGroup</string>
           </attribute>
          </widget>
         </item>
         <item row="1" column="0">
          <widget class="QCheckBox" name="showReflectionCheckBox">
           <property name="text">
            <string>显示倒影</string>
           </property>
           <property name="OptionType" stdset="0">
            <number>2</number>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">otherOptionGroup</string>
           </attribute>
          </widget>
         </item>
         <item row="1" column="1">
          <widget class="QCheckBox" name="twoDimenCheckBox">
           <property name="text">
            <string>二维显示</string>
           </property>
           <property name="OptionType" stdset="0">
            <number>3</number>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">otherOptionGroup</string>
           </attribute>
          </widget>
         </item>
        </layout>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <widget class="QStackedWidget" name="stackedWidget"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>720</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections>
  <connection>
   <sender>horAngleSpinBox</sender>
   <signal>valueChanged(int)</signal>
   <receiver>CMainWindow</receiver>
   <slot>on_angleValueChange(int)</slot>
   <hints>
    <hint type="sourcelabel">
     <x>110</x>
     <y>130</y>
    </hint>
    <hint type="destinationlabel">
     <x>-83</x>
     <y>239</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>verAngleSpinBox</sender>
   <signal>valueChanged(int)</signal>
   <receiver>CMainWindow</receiver>
   <slot>on_angleValueChange(int)</slot>
   <hints>
    <hint type="sourcelabel">
     <x>273</x>
     <y>131</y>
    </hint>
    <hint type="destinationlabel">
     <x>-157</x>
     <y>269</y>
    </hint>
   </hints>
  </connection>
 </connections>
 <slots>
  <slot>on_angleValueChange(int)</slot>
 </slots>
 <buttongroups>
  <buttongroup name="otherOptionGroup">
   <property name="exclusive">
    <bool>false</bool>
   </property>
  </buttongroup>
 </buttongroups>
</ui>

main.cpp

#include "CMainWindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CMainWindow w;
    w.show();

    return a.exec();
}

总结

由于三图存在于同一个简单的Demo中,功能不是很完善,和QChart一样,各个图表的选项独立最好(就是说每次点击按钮只改变当前图表的属性),有兴趣的伙伴可以优化此功能; 在开发过程中,多多少少还是会有碰壁,另外其实还有许多BUG都没有正面处理,原本想多种函数通用实现样式,最后发现样式多多少少有些差别,不得不限制某些控件在不同图表中的状态;除此之外还有很多值得我们去发掘的功能和BUG,学无止境,冲鸭😆。
现在也是很晚了,那就休息了,晚安吧😁。

相关文章

Qt之QChart各个图表的简单使用(含源码+注释)

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除

--------------------------- Qt Data Visualization 5.7.0 --------------------------- Qt Data Visualization module provides multiple graph types to visualize data in 3D space both with C++ and Qt Quick 2. System Requirements =================== - Qt 5.2.1 or newer - OpenGL 2.1 or newer (recommended) or OpenGL ES2 (reduced feature set) - Manipulating Qt Data Visualization graphs with QML Designer requires Qt Creator 3.3 or newer Building ======== Configure the project with qmake: qmake After running qmake, build the project with make: (Linux) make (Windows with MinGw) mingw32-make (Windows with Visual Studio) nmake (OS X) make The above generates the default makefiles for your configuration, which is typically the release build if you are using precompiled binary Qt distribution. To build both debug and release, or one specifically, use one of the following qmake lines instead. For debug builds: qmake CONFIG+=debug make or qmake CONFIG+=debug_and_release make debug For release builds: qmake CONFIG+=release make or qmake CONFIG+=debug_and_release make release For both builds (Windows/OS X only): qmake CONFIG+="debug_and_release build_all" make After building, install the module to your Qt directory: make install If you want to uninstall the module: make uninstall Building as a statically linked library ======================================= The same as above applies, you will just have to add static to the CONFIG: qmake CONFIG+=static Documentation ============= The documentation can be generated with: make docs The documentation is generated into the doc folder under the build folder. Both Qt Assistant (qtdatavisualization.qch) and in HTML format (qtdatavisualization subfolder) documentation is generated. Please refer to the generated documentation for more information: doc/qtdatavisualization/qtdatavisualization-index.html Known Issues ============ - Some platforms like Android and WinRT cannot handle multiple native windows properly, so only the Qt Quick 2 versions of graphs are available in practice for those platforms. - Shadows are not supported with OpenGL ES2 (including Angle builds in Windows). - Anti-aliasing doesn&#39;t work with OpenGL ES2 (including Angle builds in Windows). - QCustom3DVolume items are not supported with OpenGL ES2 (including Angle builds in Windows). - Surfaces with non-straight rows and columns do not always render properly. - Q3DLight class (and Light3D QML item) are currently not usable for anything. - Changing most of Q3DScene properties affecting subviewports currently has no effect. - Widget based examples layout incorrectly in iOS. - Reparenting a graph to an item in another QQuickWindow is not supported. - Android builds of QML applications importing QtDataVisualization also require "QT += datavisualization" in the pro file. This is because Qt Data Visualization QML plugin has a dependency to Qt Data Visualization C++ library, which Qt Creator doesn&#39;t automatically add to the deployment package. - Only OpenGL ES2 emulation is available for software renderer (that is, when using QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL))
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lw向北.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值