• 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 
    #include 
    
    // 导入数据可视化头文件
    #include 
    //! 和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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131

    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 << "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);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434

    CMainWindow.ui

    
    <ui version="4.0">
     <class>CMainWindowclass>
     <widget class="QMainWindow" name="CMainWindow">
      <property name="geometry">
       <rect>
        <x>0x>
        <y>0y>
        <width>720width>
        <height>466height>
       rect>
      property>
      <property name="windowTitle">
       <string>CMainWindowstring>
      property>
      <widget class="QWidget" name="centralWidget">
       <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,1">
        <property name="spacing">
         <number>0number>
        property>
        <property name="leftMargin">
         <number>0number>
        property>
        <property name="topMargin">
         <number>0number>
        property>
        <property name="rightMargin">
         <number>0number>
        property>
        <property name="bottomMargin">
         <number>0number>
        property>
        <item>
         <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1,1,1">
          <property name="spacing">
           <number>10number>
          property>
          <property name="leftMargin">
           <number>7number>
          property>
          <property name="topMargin">
           <number>5number>
          property>
          <property name="rightMargin">
           <number>10number>
          property>
          <property name="bottomMargin">
           <number>5number>
          property>
          <item>
           <layout class="QHBoxLayout" name="horizontalLayout_2">
            <property name="leftMargin">
             <number>5number>
            property>
            <property name="topMargin">
             <number>5number>
            property>
            <property name="rightMargin">
             <number>5number>
            property>
            <property name="bottomMargin">
             <number>5number>
            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>5number>
             property>
             <property name="topMargin">
              <number>5number>
             property>
             <property name="rightMargin">
              <number>5number>
             property>
             <property name="bottomMargin">
              <number>5number>
             property>
             <property name="verticalSpacing">
              <number>5number>
             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>100width>
                 <height>16777215height>
                size>
               property>
               <property name="text">
                <string>开始string>
               property>
               <property name="checkable">
                <bool>truebool>
               property>
              widget>
             item>
             <item row="1" column="0" colspan="2">
              <layout class="QHBoxLayout" name="horizontalLayout">
               <property name="spacing">
                <number>0number>
               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>-180number>
                 property>
                 <property name="maximum">
                  <number>180number>
                 property>
                 <property name="singleStep">
                  <number>5number>
                 property>
                 <property name="DirectionType" stdset="0">
                  <number>0number>
                 property>
                widget>
               item>
               <item>
                <spacer name="horizontalSpacer">
                 <property name="orientation">
                  <enum>Qt::Horizontalenum>
                 property>
                 <property name="sizeHint" stdset="0">
                  <size>
                   <width>40width>
                   <height>20height>
                  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>90number>
                 property>
                 <property name="singleStep">
                  <number>5number>
                 property>
                 <property name="DirectionType" stdset="0">
                  <number>1number>
                 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>10number>
               property>
               <property name="maximum">
                <number>500number>
               property>
               <property name="value">
                <number>100number>
               property>
               <property name="orientation">
                <enum>Qt::Horizontalenum>
               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>0number>
             property>
             <property name="verticalSpacing">
              <number>10number>
             property>
             <property name="leftMargin">
              <number>5number>
             property>
             <property name="topMargin">
              <number>5number>
             property>
             <property name="rightMargin">
              <number>5number>
             property>
             <property name="bottomMargin">
              <number>5number>
             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>ThemeQtstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemePrimaryColorsstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeDigiastring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeStoneMossstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeArmyBluestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeRetrostring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeEbonystring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeIsabellestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>ThemeUserDefinedstring>
                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>MeshBarstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshCubestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshPyramidstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshConestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshCylinderstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshBevelBarstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshBevelCubestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshSpherestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshMinimalstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshArrowstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>MeshPointstring>
                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>SelectionNonestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionItemstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionRowstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionItemAndRowstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionColumnstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionItemAndColumnstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionRowAndColumnstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionItemRowAndColumnstring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionSlicestring>
                property>
               item>
               <item>
                <property name="text">
                 <string>SelectionMultiSeriesstring>
                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>5number>
             property>
             <property name="topMargin">
              <number>5number>
             property>
             <property name="rightMargin">
              <number>5number>
             property>
             <property name="bottomMargin">
              <number>5number>
             property>
             <property name="spacing">
              <number>0number>
             property>
             <item row="0" column="0">
              <widget class="QCheckBox" name="showBgCheckBox">
               <property name="text">
                <string>显示背景string>
               property>
               <property name="checked">
                <bool>truebool>
               property>
               <property name="OptionType" stdset="0">
                <number>0number>
               property>
               <attribute name="buttonGroup">
                <string notr="true">otherOptionGroupstring>
               attribute>
              widget>
             item>
             <item row="0" column="1">
              <widget class="QCheckBox" name="showGridCheckBox">
               <property name="text">
                <string>显示网格string>
               property>
               <property name="checked">
                <bool>truebool>
               property>
               <property name="OptionType" stdset="0">
                <number>1number>
               property>
               <attribute name="buttonGroup">
                <string notr="true">otherOptionGroupstring>
               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>2number>
               property>
               <attribute name="buttonGroup">
                <string notr="true">otherOptionGroupstring>
               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>3number>
               property>
               <attribute name="buttonGroup">
                <string notr="true">otherOptionGroupstring>
               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>0x>
         <y>0y>
         <width>720width>
         <height>23height>
        rect>
       property>
      widget>
      <widget class="QStatusBar" name="statusBar"/>
     widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections>
      <connection>
       <sender>horAngleSpinBoxsender>
       <signal>valueChanged(int)signal>
       <receiver>CMainWindowreceiver>
       <slot>on_angleValueChange(int)slot>
       <hints>
        <hint type="sourcelabel">
         <x>110x>
         <y>130y>
        hint>
        <hint type="destinationlabel">
         <x>-83x>
         <y>239y>
        hint>
       hints>
      connection>
      <connection>
       <sender>verAngleSpinBoxsender>
       <signal>valueChanged(int)signal>
       <receiver>CMainWindowreceiver>
       <slot>on_angleValueChange(int)slot>
       <hints>
        <hint type="sourcelabel">
         <x>273x>
         <y>131y>
        hint>
        <hint type="destinationlabel">
         <x>-157x>
         <y>269y>
        hint>
       hints>
      connection>
     connections>
     <slots>
      <slot>on_angleValueChange(int)slot>
     slots>
     <buttongroups>
      <buttongroup name="otherOptionGroup">
       <property name="exclusive">
        <bool>falsebool>
       property>
      buttongroup>
     buttongroups>
    ui>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562
    • 563
    • 564
    • 565
    • 566
    • 567
    • 568
    • 569
    • 570
    • 571
    • 572
    • 573
    • 574
    • 575
    • 576
    • 577
    • 578
    • 579
    • 580
    • 581
    • 582
    • 583
    • 584
    • 585
    • 586
    • 587
    • 588
    • 589
    • 590
    • 591
    • 592
    • 593
    • 594
    • 595

    main.cpp

    #include "CMainWindow.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        CMainWindow w;
        w.show();
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    总结

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

    相关文章

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

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

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

  • 相关阅读:
    debug技巧之使用arthas调试
    Linux CentOS7 添加中文输入法
    每个数据工程师都应该了解和使用的10 个 ChatGPT 提示
    Selenium的安装以及简单使用
    kafka教程
    找工作----C++面试题库
    除硅树脂-HP4500
    Android使用高德地图实现运动轨迹绘制和轨迹回放
    【git】Git 指令统计代码行数
    开源组件 | 一款好用的小程序生成图片库
  • 原文地址:https://blog.csdn.net/wj584652425/article/details/126276932