十、Qt三维图表

一、Data Visualization模块概述

Data Visualization的三维显示功能主要有三种三维图形来实现,三各类的父类都是QAbstract3DGraph,从QWindow继承而来。这三类分别是:
  • 三维柱状图Q3DBar
  • 三维空间散点Q3DScatter
  • 三维曲面Q3DSurface

1、相关类的继承关系

(1)图形类

QWindow
	QAbstract3DGraph
		Q3DBar
		Q3DScatter
		Q3DSurface

(2)数据序列类

QAbstract3DSeries
	QBar3DSeries
	QScatter3DSeries
	QSurface3DSeries

(3)轴类

QAbstract3DAxis
	QCategory3DAxis
	QValue3DAxis

(4)数据代理类

数据代理类与序列对应,用于存储序列的数据的类。
QAbstractDataProxy
	QBarDataProxy
		QItemModelBarDataProxy
	QScatterDataProxy
		QItemModelScatterDataProxy
	QSurfaceDataProxy
		QHeightMapSurfaceDataProxy
		QItemModelSurfaceDataProxy

2、使用方法

(1)工程添加

QT += datavisualization

(2)代码中添加头文件与命名空间

#include 
using namespace QtDataVisualization;

二、三维柱状图

1、实现程序

十、Qt三维图表_第1张图片

(1)创建项目,基于QMainWindow

(2)添加组件

十、Qt三维图表_第2张图片

(3)初始化

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QSplitter *splitter = new QSplitter(Qt::Horizontal);
    splitter->addWidget(ui->groupBox);


    initGraph3D();
    splitter->addWidget(createWindowContainer(graph3D));
    setCentralWidget(splitter);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initGraph3D()
{
    graph3D = new Q3DBars;

    // 创建坐标系统
    QStringList rowLabs, colLabs;
    rowLabs << "row1" << "row2" << "row3";
    colLabs << "col1" << "col2" << "col3" << "col4" << "col5";

    QValue3DAxis *axisV = new QValue3DAxis;
    axisV->setTitle("Value");
    axisV->setTitleVisible(true);

    QCategory3DAxis * axisCol = new QCategory3DAxis;
    axisCol->setTitle("Column");
    axisCol->setTitleVisible(true);
    axisCol->setLabels(colLabs);

    QCategory3DAxis * axisRow = new QCategory3DAxis;
    axisRow->setTitle("Row");
    axisRow->setTitleVisible(true);
    axisRow->setLabels(rowLabs);

    graph3D->setValueAxis(axisV);
    graph3D->setColumnAxis(axisCol);
    graph3D->setRowAxis(axisRow);

    // 创建数据序列
    QBar3DSeries *series = new QBar3DSeries;
    series->setMesh(QAbstract3DSeries::MeshCylinder); // 形状
    series->setItemLabelFormat("(@rowLabel,@colLabel):%.1f");

    // 添加数据
    QBarDataArray *dataArray = new QBarDataArray;
    dataArray->reserve(rowLabs.count()); // 三行数据

    qsrand(QTime::currentTime().second());

    for (int i = 0; i < rowLabs.count(); ++i)
    {
        QBarDataRow *dataRow = new QBarDataRow;

        for (int j = 0; j < 5; ++j)
        {
            (*dataRow) << (qrand() % 10);
        }

        dataArray->append(dataRow);
    }

    series->dataProxy()->resetArray(dataArray);
    graph3D->addSeries(series);
}

十、Qt三维图表_第3张图片

(4)实现功能

void MainWindow::on_cboxCarmera_currentIndexChanged(int index)
{
    graph3D->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPreset(index));
}

void MainWindow::on_hSliderLevel_valueChanged(int value)
{
    Q_UNUSED(value);
    int xRot = ui->hSliderLevel->value();
    int yRot = ui->hSliderVertical->value();
    int zoom = ui->hSliderScale->value();
    graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}

void MainWindow::on_hSliderVertical_valueChanged(int value)
{
    Q_UNUSED(value);
    int xRot = ui->hSliderLevel->value();
    int yRot = ui->hSliderVertical->value();
    int zoom = ui->hSliderScale->value();
    graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}

void MainWindow::on_hSliderScale_valueChanged(int value)
{
    Q_UNUSED(value);
    int xRot = ui->hSliderLevel->value();
    int yRot = ui->hSliderVertical->value();
    int zoom = ui->hSliderScale->value();
    graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}

void MainWindow::on_cboxTheme_currentIndexChanged(int index)
{
    graph3D->activeTheme()->setType(Q3DTheme::Theme(index));
}

void MainWindow::on_cboxStyle_currentIndexChanged(int index)
{
    QBar3DSeries *series = graph3D->seriesList().at(0);
    series->setMesh(QAbstract3DSeries::Mesh(index));
}

void MainWindow::on_cboxMode_currentIndexChanged(int index)
{
    graph3D->setSelectionMode(QAbstract3DGraph::SelectionFlags(index));
}

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

#include 
void MainWindow::on_btnItemColor_clicked()
{
    QBar3DSeries *series = graph3D->seriesList().at(0);
    QColor color = series->baseColor();
    color = QColorDialog::getColor(color);
    if(color.isValid())
    {
        series->setBaseColor(color);
    }
}

void MainWindow::on_checkBoxBack_clicked(bool checked)
{
    graph3D->activeTheme()->setBackgroundEnabled(checked);
}

void MainWindow::on_checkBoxBackNetwork_clicked(bool checked)
{
    graph3D->activeTheme()->setGridEnabled(checked);
}

void MainWindow::on_checkBoxSmooth_clicked(bool checked)
{
    QBar3DSeries *series = graph3D->seriesList().at(0);
    series->setMeshSmooth(checked);
}

void MainWindow::on_checkBoxReflection_clicked(bool checked)
{
    graph3D->setReflection(checked);
}

void MainWindow::on_checkBoxValueAxis_clicked(bool checked)
{
    graph3D->valueAxis()->setReversed(checked);
}

void MainWindow::on_checkBoxItemLabel_clicked(bool checked)
{
    QBar3DSeries *series = graph3D->seriesList().at(0);
    series->setItemLabelVisible(checked);
}

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

void MainWindow::on_checkBoxAxisLabelBack_clicked(bool checked)
{
    graph3D->activeTheme()->setLabelBackgroundEnabled(checked);
}

三、三维散点图

1、实现程序

十、Qt三维图表_第4张图片

(1)创建项目,基于QMainWindow

(2)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QSplitter *splitter = new QSplitter(Qt::Horizontal);
    splitter->addWidget(ui->groupBox);


    initGraph3D();
    splitter->addWidget(createWindowContainer(graph3D));
    setCentralWidget(splitter);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initGraph3D()
{
    graph3D = new Q3DScatter;

    // 创建坐标系统
    graph3D->axisX()->setTitle("X轴");
    graph3D->axisX()->setTitleVisible(true);
    graph3D->axisY()->setTitle("Y轴");
    graph3D->axisY()->setTitleVisible(true);
    graph3D->axisZ()->setTitle("Z轴");
    graph3D->axisZ()->setTitleVisible(true);

    // 创建数据序列
    QScatterDataProxy *porxy = new QScatterDataProxy;
    QScatter3DSeries *series = new QScatter3DSeries(porxy);
    //    series->setMesh(QAbstract3DSeries::MeshCylinder); // 形状
    series->setItemLabelFormat("(@rowLabel,@colLabel):%.1f");
    series->setItemSize(0.2);
    graph3D->addSeries(series);

    // 添加数据
    int N = 41;
    QScatterDataArray *dataArray = new QScatterDataArray;
    dataArray->resize(N * N);
    QScatterDataItem *item = &dataArray->first();


    // 摩西跟草帽算法
    float x, y, z;
    x = -10;
    for (int i = 0; i < N; ++i)
    {
        y = -10;
        for (int j = 1; j <= N; ++j)
        {
            z = qSqrt(x * x + y * y);
            if(z != 0)
            {
                z = 10 * qSin(z) / z;
            }
            else
            {
                z = 10;
            }
            // 图形库的坐标系
            item->setPosition(QVector3D(x, z, y));
            item++;
            y += 0.5;
        }
        x += 0.5;
    }

    series->dataProxy()->resetArray(dataArray);
}

void MainWindow::on_cboxCarmera_currentIndexChanged(int index)
{
    graph3D->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPreset(index));
}

void MainWindow::on_hSliderLevel_valueChanged(int value)
{
    Q_UNUSED(value);
    int xRot = ui->hSliderLevel->value();
    int yRot = ui->hSliderVertical->value();
    int zoom = ui->hSliderScale->value();
    graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}

void MainWindow::on_hSliderVertical_valueChanged(int value)
{
    Q_UNUSED(value);
    int xRot = ui->hSliderLevel->value();
    int yRot = ui->hSliderVertical->value();
    int zoom = ui->hSliderScale->value();
    graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}

void MainWindow::on_hSliderScale_valueChanged(int value)
{
    Q_UNUSED(value);
    int xRot = ui->hSliderLevel->value();
    int yRot = ui->hSliderVertical->value();
    int zoom = ui->hSliderScale->value();
    graph3D->scene()->activeCamera()->setCameraPosition(xRot, yRot, zoom);
}

void MainWindow::on_cboxTheme_currentIndexChanged(int index)
{
    graph3D->activeTheme()->setType(Q3DTheme::Theme(index));
}

void MainWindow::on_cboxStyle_currentIndexChanged(int index)
{
    QScatter3DSeries *series = graph3D->seriesList().at(0);
    series->setMesh(QAbstract3DSeries::Mesh(index));
}

void MainWindow::on_cboxMode_currentIndexChanged(int index)
{
    graph3D->setSelectionMode(QAbstract3DGraph::SelectionFlags(index));
}

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

#include 
void MainWindow::on_btnItemColor_clicked()
{
    QScatter3DSeries *series = graph3D->seriesList().at(0);
    QColor color = series->baseColor();
    color = QColorDialog::getColor(color);
    if(color.isValid())
    {
        series->setBaseColor(color);
    }
}

void MainWindow::on_checkBoxBack_clicked(bool checked)
{
    graph3D->activeTheme()->setBackgroundEnabled(checked);
}

void MainWindow::on_checkBoxBackNetwork_clicked(bool checked)
{
    graph3D->activeTheme()->setGridEnabled(checked);
}

void MainWindow::on_checkBoxSmooth_clicked(bool checked)
{
    QScatter3DSeries *series = graph3D->seriesList().at(0);
    series->setMeshSmooth(checked);
}

void MainWindow::on_checkBoxReflection_clicked(bool checked)
{
    graph3D->setReflection(checked);
}

void MainWindow::on_checkBoxValueAxis_clicked(bool checked)
{
    graph3D->axisY()->setReversed(checked);
}

void MainWindow::on_checkBoxItemLabel_clicked(bool checked)
{
    QScatter3DSeries *series = graph3D->seriesList().at(0);
    series->setItemLabelVisible(checked);
}

void MainWindow::on_checkBoxAxisBack_clicked(bool checked)
{
    graph3D->axisY()->setTitleVisible(checked);
    graph3D->axisX()->setTitleVisible(checked);
    graph3D->axisZ()->setTitleVisible(checked);
}

void MainWindow::on_checkBoxAxisLabelBack_clicked(bool checked)
{
    graph3D->activeTheme()->setLabelBackgroundEnabled(checked);
}

四、三维曲面图

1、实现程序

十、Qt三维图表_第5张图片

(1)创建项目,基于QMainWindow

(2)添加组件

十、Qt三维图表_第6张图片

(3)初始化

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QSplitter *splitter = new QSplitter;
    splitter->addWidget(ui->groupBox);
    init3DGraph();
    splitter->addWidget(createWindowContainer(graph3D));
    setCentralWidget(splitter);

    // 设置按钮的渐变色
    QLinearGradient lgColor1(0, 0, 100, 0);
    lgColor1.setColorAt(1.0, Qt::black);
    lgColor1.setColorAt(0.67, Qt::blue);
    lgColor1.setColorAt(0.33, Qt::red);
    lgColor1.setColorAt(0, Qt::yellow);
    QPixmap mp(160, 20);
    QPainter painter(&mp);
    painter.setBrush(lgColor1);
    painter.drawRect(0, 0, 160, 20);
    ui->btnColors1->setIcon(QIcon(mp));
    ui->btnColors1->setIconSize(QSize(160, 20));

    lgColor1.setColorAt(1.0, Qt::darkBlue);
    lgColor1.setColorAt(0.5, Qt::yellow);
    lgColor1.setColorAt(0.2, Qt::red);
    lgColor1.setColorAt(0, Qt::darkRed);
    painter.setBrush(lgColor1);
    painter.drawRect(0, 0, 160, 20);
    ui->btnColors2->setIcon(QIcon(mp));
    ui->btnColors2->setIconSize(QSize(160, 20));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init3DGraph()
{
    graph3D = new Q3DSurface;

    graph3D->axisX()->setTitle("X轴");
    graph3D->axisX()->setTitleVisible(true);
    graph3D->axisX()->setRange(-11, 11);
    graph3D->axisY()->setTitle("Y轴");
    graph3D->axisY()->setTitleVisible(true);
    graph3D->axisZ()->setTitle("Z轴");
    graph3D->axisZ()->setTitleVisible(true);
    graph3D->axisZ()->setRange(-11, 11);


    QSurfaceDataProxy *proxy = new QSurfaceDataProxy;
    series = new QSurface3DSeries(proxy);
    series->setDrawMode(QSurface3DSeries::DrawSurface);
    series->setMeshSmooth(true); // 光滑曲面
    graph3D->addSeries(series);

    QSurfaceDataArray *dataArray = new QSurfaceDataArray;

    // 摩西跟草帽算法
    int N = 41;
    dataArray->reserve(N);
    float x, y, z;
    x = -10;
    for (int i = 0; i < N; ++i)
    {
        QSurfaceDataRow *newRow = new QSurfaceDataRow(N);

        y = -10;
        int index = 0;
        for (int j = 1; j <= N; ++j)
        {
            z = qSqrt(x * x + y * y);
            if(z != 0)
            {
                z = 10 * qSin(z) / z;
            }
            else
            {
                z = 10;
            }
            // 图形库的坐标系
            (*newRow)[index++].setPosition(QVector3D(x, z, y));
            y += 0.5;
        }
        x += 0.5;
        *dataArray << newRow;
    }

    series->dataProxy()->resetArray(dataArray);

}

(4)设置颜色

#include 
void MainWindow::on_btnOneColor_clicked()
{
    QColor color = series->baseColor();
    color = QColorDialog::getColor(color);
    if(color.isValid())
    {
        series->setBaseColor(color);
        series->setColorStyle(Q3DTheme::ColorStyleUniform);
    }
}

void MainWindow::on_btnColors1_clicked()
{
    QLinearGradient lgColor1(0, 0, 100, 0);
    lgColor1.setColorAt(1.0, Qt::black);
    lgColor1.setColorAt(0.67, Qt::blue);
    lgColor1.setColorAt(0.33, Qt::red);
    lgColor1.setColorAt(0, Qt::yellow);
    series->setBaseGradient(lgColor1);
    series->setColorStyle(Q3DTheme::ColorStyleRangeGradient); //设置渐变色
}

void MainWindow::on_btnColors2_clicked()
{
    QLinearGradient lgColor1(0, 0, 100, 0);
    lgColor1.setColorAt(1.0, Qt::darkBlue);
    lgColor1.setColorAt(0.5, Qt::yellow);
    lgColor1.setColorAt(0.2, Qt::red);
    lgColor1.setColorAt(0, Qt::darkRed);
    series->setBaseGradient(lgColor1);
    series->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
}

五、三维地形图

1、实现程序

十、Qt三维图表_第7张图片

(1)拷贝上一个项目

(2)添加图片资源文件

(3)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QSplitter *splitter = new QSplitter;
    splitter->addWidget(ui->groupBox);
    init3DGraph();
    splitter->addWidget(createWindowContainer(graph3D));
    setCentralWidget(splitter);

    // 设置按钮的渐变色
    QLinearGradient lgColor1(0, 0, 100, 0);
    lgColor1.setColorAt(1.0, Qt::black);
    lgColor1.setColorAt(0.67, Qt::blue);
    lgColor1.setColorAt(0.33, Qt::red);
    lgColor1.setColorAt(0, Qt::yellow);
    QPixmap mp(160, 20);
    QPainter painter(&mp);
    painter.setBrush(lgColor1);
    painter.drawRect(0, 0, 160, 20);
    ui->btnColors1->setIcon(QIcon(mp));
    ui->btnColors1->setIconSize(QSize(160, 20));

    lgColor1.setColorAt(1.0, Qt::darkBlue);
    lgColor1.setColorAt(0.5, Qt::yellow);
    lgColor1.setColorAt(0.2, Qt::red);
    lgColor1.setColorAt(0, Qt::darkRed);
    painter.setBrush(lgColor1);
    painter.drawRect(0, 0, 160, 20);
    ui->btnColors2->setIcon(QIcon(mp));
    ui->btnColors2->setIconSize(QSize(160, 20));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init3DGraph()
{
    graph3D = new Q3DSurface;

    graph3D->axisX()->setTitle("东--西");
    graph3D->axisX()->setTitleVisible(true);
    graph3D->axisX()->setLabelFormat("%.2f米");
    graph3D->axisZ()->setTitle("南--北");
    graph3D->axisZ()->setTitleVisible(true);
    graph3D->axisY()->setTitle("海拔");
    graph3D->axisY()->setTitleVisible(true);

    QImage mapImage(":/images/images/map.png");
    QHeightMapSurfaceDataProxy *proxy = new QHeightMapSurfaceDataProxy(mapImage);
    proxy->setValueRanges(-5000, 5000, -5000, 5000);
    series = new QSurface3DSeries(proxy);
    series->setDrawMode(QSurface3DSeries::DrawSurface);
    graph3D->addSeries(series);
}

void MainWindow::on_cboxSurfaceStyle_currentIndexChanged(int index)
{
    series->setDrawMode(QSurface3DSeries::DrawFlags(index + 1));
}

#include 
void MainWindow::on_btnOneColor_clicked()
{
    QColor color = series->baseColor();
    color = QColorDialog::getColor(color);
    if(color.isValid())
    {
        series->setBaseColor(color);
        series->setColorStyle(Q3DTheme::ColorStyleUniform);
    }
}

void MainWindow::on_btnColors1_clicked()
{
    QLinearGradient lgColor1(0, 0, 100, 0);
    lgColor1.setColorAt(1.0, Qt::black);
    lgColor1.setColorAt(0.67, Qt::blue);
    lgColor1.setColorAt(0.33, Qt::red);
    lgColor1.setColorAt(0, Qt::yellow);
    series->setBaseGradient(lgColor1);
    series->setColorStyle(Q3DTheme::ColorStyleRangeGradient); //设置渐变色
}

void MainWindow::on_btnColors2_clicked()
{
    QLinearGradient lgColor1(0, 0, 100, 0);
    lgColor1.setColorAt(1.0, Qt::darkBlue);
    lgColor1.setColorAt(0.5, Qt::yellow);
    lgColor1.setColorAt(0.2, Qt::red);
    lgColor1.setColorAt(0, Qt::darkRed);
    series->setBaseGradient(lgColor1);
    series->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
}

void MainWindow::on_cboxMode_currentIndexChanged(int index)
{
    switch (index)
    {
    case 0:
        graph3D->setSelectionMode(QAbstract3DGraph::SelectionNone);
        break;
    case 1:
        graph3D->setSelectionMode(QAbstract3DGraph::SelectionItem);
        break;
    case 2:
        graph3D->setSelectionMode(QAbstract3DGraph::SelectionRow |
                                  QAbstract3DGraph::SelectionSlice);
        break;
    case 3:
        graph3D->setSelectionMode(QAbstract3DGraph::SelectionColumn |
                                  QAbstract3DGraph::SelectionSlice);
        break;
    default:
        break;
    }
}

你可能感兴趣的:(QT,qt)