qt提供了q3d進行三維開發,雖然這個框架沒有得到大量運用也不是那麼成功,效能上也有很大的欠缺,但是普通的點到為止的應用展示還是可以的。
其中就包括華麗絢爛的三維圖表,資料量不大的時候是可以使用的。
前面介紹了基礎的q3d散點圖、柱狀圖,本篇介紹基礎的三維曲面圖。
依賴QtDataVisualization。在安裝qt的時候要選擇安裝QtDataVisualization模組。
Q3D的散點圖,效能大約支撐1000個點可以不卡頓,具體依賴pc,1000個點是什麼 概念,可以理解為:10x10x10的區域,每個區域一個資料點。
Q3D的柱狀圖,效能跟散點圖類似。
Q3D的柱狀圖,效能跟散點圖類似。
Q3DSurface類提供了渲染3D曲面圖的方法。該類使開發人員能夠渲染3D表面圖,並通過自由旋轉場景來檢視它們。可以通過QSurface3DSeries控制曲面的視覺財產,例如繪製模式和著色。
Q3DSurface通過在使用者用滑鼠左鍵點選的資料點上顯示高亮顯示的球(當使用預設輸入處理程式時)或通過QSurface3DSeries進行選擇來支援選擇。選擇指標附帶一個標籤,在預設情況下,該標籤顯示資料點的值和點的座標。
軸上顯示的值範圍和標籤格式可以通過QValue3DAxis進行控制。
要旋轉圖形,請按住滑鼠右鍵並移動滑鼠。縮放是使用滑鼠滾輪完成的。兩者都假設預設的輸入處理程式正在使用中。
如果沒有將任何軸明確設定為Q3DSurface,則會建立不帶標籤的臨時預設軸。這些預設軸可以通過軸存取器進行修改,但只要明確設定了方向的任何軸,該方向的預設軸就會被破壞。
首先,構造Q3D曲面。由於在本例中,我們將圖形作為頂級視窗執行,因此需要清除Qt::FramelessWindowHint標誌,該標誌在預設情況下設定:
Q3DSurface surface;
surface.setFlags(surface.flags() ^ Qt::FramelessWindowHint);
現在Q3DSurface已準備好接收要渲染的資料。建立資料元素以接收值:
QSurfaceDataArray *data = new QSurfaceDataArray;
QSurfaceDataRow *dataRow1 = new QSurfaceDataRow;
QSurfaceDataRow *dataRow2 = new QSurfaceDataRow;
首先將資料餵給行元素,然後將它們的指標新增到資料元素:
*dataRow1 << QVector3D(0.0f, 0.1f, 0.5f) << QVector3D(1.0f, 0.5f, 0.5f);
*dataRow2 << QVector3D(0.0f, 1.8f, 1.0f) << QVector3D(1.0f, 1.2f, 1.0f);
*data << dataRow1 << dataRow2;、
建立新系列併為其設定資料:
QSurface3DSeries *series = new QSurface3DSeries;
series->dataProxy()->resetArray(data);
surface.addSeries(series);
最後,設定為可見:
surface.show();
建立和顯示此圖所需的完整程式碼為:
#include <QtDataVisualization>
using namespace QtDataVisualization;
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
Q3DSurface surface;
surface.setFlags(surface.flags() ^ Qt::FramelessWindowHint);
QSurfaceDataArray *data = new QSurfaceDataArray;
QSurfaceDataRow *dataRow1 = new QSurfaceDataRow;
QSurfaceDataRow *dataRow2 = new QSurfaceDataRow;
*dataRow1 << QVector3D(0.0f, 0.1f, 0.5f) << QVector3D(1.0f, 0.5f, 0.5f);
*dataRow2 << QVector3D(0.0f, 1.8f, 1.0f) << QVector3D(1.0f, 1.2f, 1.0f);
*data << dataRow1 << dataRow2;
QSurface3DSeries *series = new QSurface3DSeries;
series->dataProxy()->resetArray(data);
surface.addSeries(series);
surface.show();
return app.exec();
}
執行效果:
場景可以被旋轉、放大,並且可以選擇一個專案來檢視其位置,但在這個最小的程式碼範例中不包括其他互動。
如何確認,則是在幫助檔案中檢視是否有Q3dscatter類。一般是安裝了模組才會有對應的幫助檔案。沒有則重新安裝qt或者單獨安裝該模組。
Q3d是在資料視覺化模組中,需要在pro或者pri組態檔中新增。
QT += datavisualization
使用到Q3DBar相關類中新增標頭檔案,主要使用到Q3DBar、QBar3DSeries、QBarDataRow等等。
#include <Q3DBars>
#include <Q3DTheme>
#include <QBar3DSeries>
#include <QVector3D>
這時候還是無法使用對應的類,需要新增名稱空間才行:
using namespace QtDataVisualization;
下面是包含註釋的Q3DSurface基礎構建流程(注意軸的顯示,檢視末尾「入坑一」,注意資料的成面規則,檢視「入坑二」
_pQ3DSurface = new Q3DSurface();
_pContainer = QWidget::createWindowContainer(_pQ3DSurface, this);
// 設定軸文字
{
// 注意笛卡爾座標
_pQ3DSurface->axisX()->setTitle("經度(°)");
_pQ3DSurface->axisX()->setTitleVisible(true);
_pQ3DSurface->axisY()->setTitle("高度(m)");
_pQ3DSurface->axisY()->setTitleVisible(true);
_pQ3DSurface->axisZ()->setTitle("緯度(°)");
_pQ3DSurface->axisZ()->setTitleVisible(true);
}
// 設定軸範圍
{
// 注意笛卡爾座標
_pQ3DSurface->axisX()->setRange(0, 359);
_pQ3DSurface->axisY()->setRange(0, 100);
_pQ3DSurface->axisZ()->setRange(0, 359);
}
// 生成一個曲線
_pSurface3DSeries = new QSurface3DSeries(_pQ3DSurface);
// 設定渲染平滑
_pSurface3DSeries->setMeshSmooth(true);
// 設定渲染模式
// DrawWireframe : 繪製柵格
// DrawSurface : 繪製表面
// DrawSurfaceAndWireframe : 繪製柵格和圖表面
_pSurface3DSeries->setDrawMode(QSurface3DSeries::DrawSurface);
// 檢視新增該曲線
_pQ3DSurface->addSeries(_pSurface3DSeries);
// 設定陰影質量
_pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
// 設定視角
_pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);
// 設定子網格
_pQ3DSurface->activeTheme()->setGridEnabled(true);
#if 1
// 新增模擬資料
QSurfaceDataArray *pSurfaceDataArray = new QSurfaceDataArray;
#if 1
#if 1
// 這是 z 緯度
for(int n = 0; n < 360; n++)
{
QSurfaceDataRow *pSurfaceDataRow = new QSurfaceDataRow;
// 這是 x 經度
for(int m = 0; m < 360; m++)
{
// 注意與笛卡爾座標進行對映
*pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n);
}
*pSurfaceDataArray