一、Data Visualization模块概述
Data Visualization的三维显示功能主要有三种三维图形来实现,三各类的父类都是QAbstract3DGraph,从QWindow继承而来。这三类分别是:
三维柱状图Q3DBar 三维空间散点Q3DScatter 三维曲面Q3DSurface
1、相关类的继承关系
(1)图形类
QWindowQAbstract3DGraphQ3DBarQ3DScatterQ3DSurface
(2)数据序列类
QAbstract3DSeriesQBar3DSeriesQScatter3DSeriesQSurface3DSeries
(3)轴类
QAbstract3DAxisQCategory3DAxisQValue3DAxis
(4)数据代理类
数据代理类与序列对应,用于存储序列的数据的类。
QAbstractDataProxyQBarDataProxyQItemModelBarDataProxyQScatterDataProxyQItemModelScatterDataProxyQSurfaceDataProxyQHeightMapSurfaceDataProxyQItemModelSurfaceDataProxy
2、使用方法
(1)工程添加
QT += datavisualization
(2)代码中添加头文件与命名空间
using namespace QtDataVisualization;
二、三维柱状图
1、实现程序
(1)创建项目,基于QMainWindow
(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) ;
}
(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) ;
}
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、实现程序
(1)创建项目,基于QMainWindow
(2)实现功能
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) ;
}
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、实现程序
(1)创建项目,基于QMainWindow
(2)添加组件
(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)设置颜色
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、实现程序
(1)拷贝上一个项目
(2)添加图片资源文件
(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( "东--西" ) ; 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 )) ;
}
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 ; }
}