您当前的位置: 首页 >  qt

lw只吃亿点.

暂无认证

  • 8浏览

    0关注

    47博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

lw只吃亿点. 发布时间:2022-08-11 00:58:29 ,浏览量:8

文章目录
  • 一、图表操作示例图
    • 1.图表选择示例
    • 2.视角选项操作
    • 3.样式选项操作
    • 4.其他选项操作
  • 二、QtDataVisualization(个人理解)
  • 三、自定义槽函数的添加(UI界面)
  • 四、源码
    • CMainWindow.h
    • CMainWindow.cpp
    • CMainWindow.ui
    • main.cpp
  • 总结
  • 相关文章

一、图表操作示例图 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 
#include 

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

namespace Ui {
class CMainWindow;
}
//! 设置一个模板函数
template
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   m_graphLsit;    // 图表容器指针

    int                         m_timer;        // 定时器对象

};

#endif // CMAINWINDOW_H

CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"
#include 

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 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(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(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(graph), index);
            break;
        }
        case 1:
        {
            // 调用样式模板函数
            setSeriesStyle(dynamic_cast(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
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


 CMainWindow
 
  
   
    0
    0
    720
    466
   
  
  
   CMainWindow
  
  
   
    
     0
    
    
     0
    
    
     0
    
    
     0
    
    
     0
    
    
     
      
       10
      
      
       7
      
      
       5
      
      
       10
      
      
       5
      
      
       
        
         5
        
        
         5
        
        
         5
        
        
         5
        
        
         
          
           三维(图)类型:
          
         
        
        
         
          
           
            三维柱状图
           
          
          
           
            三维散点图
           
          
          
           
            三维曲面图
           
          
         
        
       
      
      
       
        
         视角选项
        
        
         
          5
         
         
          5
         
         
          5
         
         
          5
         
         
          5
         
         
          
           
            自动切换视角:
           
          
         
         
          
           
            
             100
             16777215
            
           
           
            开始
           
           
            true
           
          
         
         
          
           
            0
           
           
            
             
              水平视角:
             
            
           
           
            
             
              °
             
             
              
             
             
              -180
             
             
              180
             
             
              5
             
             
              0
             
            
           
           
            
             
              Qt::Horizontal
             
             
              
               40
               20
              
             
            
           
           
            
             
              垂直视角:
             
            
           
           
            
             
              °
             
             
              
             
             
              90
             
             
              5
             
             
              1
             
            
           
          
         
         
          
           
            缩放:
           
          
         
         
          
           
            10
           
           
            500
           
           
            100
           
           
            Qt::Horizontal
           
          
         
        
       
      
      
       
        
         样式选项
        
        
         
          0
         
         
          10
         
         
          5
         
         
          5
         
         
          5
         
         
          5
         
         
          
           
            主题:
           
          
         
         
          
           
            
             ThemeQt
            
           
           
            
             ThemePrimaryColors
            
           
           
            
             ThemeDigia
            
           
           
            
             ThemeStoneMoss
            
           
           
            
             ThemeArmyBlue
            
           
           
            
             ThemeRetro
            
           
           
            
             ThemeEbony
            
           
           
            
             ThemeIsabelle
            
           
           
            
             ThemeUserDefined
            
           
          
         
         
          
           
            系列样式:
           
          
         
         
          
           
            
             MeshBar
            
           
           
            
             MeshCube
            
           
           
            
             MeshPyramid
            
           
           
            
             MeshCone
            
           
           
            
             MeshCylinder
            
           
           
            
             MeshBevelBar
            
           
           
            
             MeshBevelCube
            
           
           
            
             MeshSphere
            
           
           
            
             MeshMinimal
            
           
           
            
             MeshArrow
            
           
           
            
             MeshPoint
            
           
          
         
         
          
           
            选择模式:
           
          
         
         
          
           
            
             SelectionNone
            
           
           
            
             SelectionItem
            
           
           
            
             SelectionRow
            
           
           
            
             SelectionItemAndRow
            
           
           
            
             SelectionColumn
            
           
           
            
             SelectionItemAndColumn
            
           
           
            
             SelectionRowAndColumn
            
           
           
            
             SelectionItemRowAndColumn
            
           
           
            
             SelectionSlice
            
           
           
            
             SelectionMultiSeries
            
           
          
         
        
       
      
      
       
        
         其他选项
        
        
         
          5
         
         
          5
         
         
          5
         
         
          5
         
         
          0
         
         
          
           
            显示背景
           
           
            true
           
           
            0
           
           
            otherOptionGroup
           
          
         
         
          
           
            显示网格
           
           
            true
           
           
            1
           
           
            otherOptionGroup
           
          
         
         
          
           
            显示倒影
           
           
            2
           
           
            otherOptionGroup
           
          
         
         
          
           
            二维显示
           
           
            3
           
           
            otherOptionGroup
           
          
         
        
       
      
     
    
    
     
    
   
  
  
   
    
     0
     0
     720
     23
    
   
  
  
 
 
 
 
  
   horAngleSpinBox
   valueChanged(int)
   CMainWindow
   on_angleValueChange(int)
   
    
     110
     130
    
    
     -83
     239
    
   
  
  
   verAngleSpinBox
   valueChanged(int)
   CMainWindow
   on_angleValueChange(int)
   
    
     273
     131
    
    
     -157
     269
    
   
  
 
 
  on_angleValueChange(int)
 
 
  
   
    false
   
  
 


main.cpp
#include "CMainWindow.h"
#include 

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

    return a.exec();
}

总结

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

相关文章

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

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

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

关注
打赏
1654352885
查看更多评论
立即登录/注册

微信扫码登录

0.0973s