2014-04-22 16 views
11

Tôi thích sử dụng Qt3D, nhưng tất cả các ví dụ tôi thấy cho nó là các ứng dụng cửa sổ đầy đủ. Những gì tôi không thể hiểu được từ các ví dụ là làm thế nào để thêm một cửa sổ hiển thị qt3d vào một ứng dụng qt gui thông thường.Làm cách nào để hiển thị trong Qt3D trong ứng dụng GUI tiêu chuẩn?

Về cơ bản những gì tôi muốn là một tiện ích hiển thị nhỏ cho ứng dụng Qt5 Gui của tôi.

Tôi đã xem tiện ích Qtgl, nhưng tôi thực sự muốn sử dụng khả năng quản lý cảnh của Qt3D.

Làm cách nào để hiển thị dưới dạng cửa sổ phụ bên trong cửa sổ qt Gui?

Điều này có khả thi không?

Cập nhật

Vì vậy, tôi đã thêm này để MainWindow.cpp của tôi Đó là dựa tắt của này http://blog.qt.digia.com/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/

LoadModelView *view = new LoadModelView(); //Crashes on this. Will not compile with 
              // LoadModelView(this) 

    QWidget *container = QWidget::createWindowContainer(view); 
    container->setFocusPolicy(Qt::TabFocus); 

    ui->gridLayout->addWidget(container); 

mà có vẻ đúng.

load_model.cpp của tôi bắt đầu như thế này:

#include "qglmaterialcollection.h" 
#include "qglmaterial.h" 
#include "qglscenenode.h" 
#include "qgllightmodel.h" 
#include "qglabstractscene.h" 
#include <QtGui/qmatrix4x4.h> 

#include <QPropertyAnimation> 
#include <QtCore/qmath.h> 

#define DEGREE_TO_RAD (3.1415926/180.0) 

LoadModelView::LoadModelView(QWindow *parent) 
    : QGLView(parent) 
    , m_pSTLScene(0) 

{ 
    loadModels(); 

    camera()->setCenter(QVector3D(0, 0, 0)); 
    camera()->setEye(QVector3D(0, 4, 10)); 
} 
LoadModelView::~LoadModelView() 
{ 

    delete m_pSTLScene; 
} 

void LoadModelView::paintGL(QGLPainter *painter) 
{ 
    QMatrix4x4 stlWorld; 
    stlWorld.setToIdentity(); 
    stlWorld.scale(0.1); 
    stlWorld.translate(QVector3D(2.0,0.0,0.0)); 

    painter->setStandardEffect(QGL::LitMaterial); 
    painter->setFaceColor(QGL::AllFaces,QColor(170,202,0)); 

    painter->modelViewMatrix() = camera()->modelViewMatrix() * stlWorld; 

    m_pSTLScene->mainNode()->draw(painter); 
} 

void FixNodesRecursive(int matIndex, QGLSceneNode* pNode) 
{ 
    if (pNode) { 
     pNode->setMaterialIndex(matIndex); 
     // pNode->setEffect(QGL::FlatReplaceTexture2D); 
     foreach (QGLSceneNode* pCh, pNode->children()) { 
      FixNodesRecursive(matIndex, pCh); 
     } 
    } 
} 

void LoadModelView::loadModels() 
{ 
    { 
     m_pSTLScene = QGLAbstractScene::loadScene(QLatin1String(":/models/Sheep.stl"), QString(),"CorrectNormals CorrectAcute"); 
     Q_ASSERT(m_pSTLScene!=0); 
     QGLMaterial *mat = new QGLMaterial; 
     mat->setAmbientColor(QColor(170,202,0)); 
     mat->setDiffuseColor(QColor(170,202,0)); 
     mat->setShininess(128); 

     QGLSceneNode* pSTLSceneRoot = m_pSTLScene->mainNode(); 
     int matIndex = pSTLSceneRoot->palette()->addMaterial(mat); 
     pSTLSceneRoot->setMaterialIndex(matIndex); 
     pSTLSceneRoot->setEffect(QGL::FlatReplaceTexture2D); 
     FixNodesRecursive(matIndex,pSTLSceneRoot); 

    } 

} 

Nó bị treo với: Ứng dụng này đã yêu cầu thời gian chạy để chấm dứt nó trong một cách bất thường.

và trong đầu ra ứng dụng qt: Tham số không hợp lệ được chuyển đến hàm thời gian chạy C.

EDIT Added phần còn lại của lớp trong câu hỏi

Tôi nhận thấy rằng trong ví dụ này tôi đang thích ứng http://doc.qt.digia.com/qt-quick3d-snapshot/qt3d-penguin-main-cpp.html cửa sổ được khởi tạo bằng cách nói:

LoadModelView view; 

Tuy nhiên, nói

LoadModelView *view = new LoadModelView(this) 

tai nạn

Trả lời

5

Bạn có thể phân lớp lớp QGLView kéo dài QGLWidget với hỗ trợ xem 3D:

class GLView : public QGLView 
{ 
    Q_OBJECT 

public: 
    GLView(QWidget *parent = 0); 
    ~GLView(); 

protected: 
    void initializeGL(QGLPainter *painter); 
    void paintGL(QGLPainter *painter); 

private: 
    QGLAbstractScene *m_scene; 
    QGLSceneNode *m_rootNode; 
}; 

GLView::GLView(QWidget *parent) 
    : QGLView(parent) 
    , m_scene(0) 
    , m_rootNode(0) 
{ 
    // Viewing Volume 
    camera()->setFieldOfView(25); 
    camera()->setNearPlane(1); 
    camera()->setFarPlane(1000); 

    // Position of the camera 
    camera()->setEye(QVector3D(0, 3, 4)); 

    // Direction that the camera is pointing 
    camera()->setCenter(QVector3D(0, 3, 0)); 
} 

GLView::~GLView() 
{ 
    delete m_scene; 
} 

void GLView::initializeGL(QGLPainter *painter) 
{ 
    // Background color 
    painter->setClearColor(QColor(70, 70, 70)); 

    // Load the 3d model from the file 
    m_scene = QGLAbstractScene::loadScene("models/model1/simplemodel.obj"); 

    m_rootNode = m_scene->mainNode(); 
} 

void GLView::paintGL(QGLPainter *painter) 
{ 
    m_rootNode->draw(painter); 
} 

Qt 5.1 giới thiệu các chức năng QWidget :: createWindowContainer(). Một hàm tạo ra một trình bao bọc QWidget cho một QWindow hiện có, cho phép nó sống bên trong một ứng dụng dựa trên QWidget. Bạn có thể sử dụng QWidget :: createWindowContainer mà tạo ra một QWindow trong một QWidget. Điều này cho phép đặt các lớp con QWindow trong Widget-Layouts. Bằng cách này, bạn có thể nhúng QGLView của bạn bên trong một tiện ích con.

+0

Tôi * nghĩ * Tôi đã làm điều đó. http://pastebin.com/tRi9BVwn Những gì tôi hỏi là làm thế nào để tôi có được điều này để bật lên trong một cửa sổ đã tồn tại. Bạn có thể chỉ cho bạn cách gọi từ mainwindow.cpp không? Nếu tôi cố gắng thêm w.show, sau đó view.show, thì mọi thứ sẽ bị treo. Tôi muốn một cửa sổ bình thường với các nút vv ... và một 3d render được nhúng vào bên dưới các nút. – baordog

+0

https://qt-project.org/forums/viewthread/22465 Chuỗi này nhận được câu hỏi của tôi. Không trả lời nó. – baordog

+0

Bạn có thể sử dụng QWidget :: createWindowContainer trong Qt 5.1. Tôi đã cập nhật câu trả lời thứ. – Nejat

0

Đây là cách tôi đã thực hiện trên Qt5.10. Ví dụ này cho thấy một cảnh với một hình khối. Scene bạn có thể sử dụng như một nút bấm ... Để sử dụng tiện ích này QT += 3dextras vào tệp dự án của bạn.

szene.h

#ifndef SCENE_H 
#define SCENE_H 

#include <QObject> 
#include <QWidget> 

class Scene 
     : public QWidget 
{ 
    Q_OBJECT 

private: 
    QWidget *container; 

public: 
    explicit Scene(QWidget *parent = nullptr); 

protected: 
    // reimplementation needed to handle resize events 
    // http://doc.qt.io/qt-5/qwidget.html#resizeEvent 
    void 
    resizeEvent (QResizeEvent * event); 

public slots: 
    void 
    resizeView(QSize size); 
}; 

#endif // SCENE_H 

cảnh.cpp

#include "scene.h" 

#include <Qt3DExtras/Qt3DWindow> 
#include <Qt3DExtras/QForwardRenderer> 
#include <QQuaternion> 
#include <Qt3DCore/QEntity> 
#include <Qt3DCore/QTransform> 
#include <Qt3DRender/QCamera> 
#include <Qt3DExtras/QCuboidMesh> 
#include <Qt3DExtras/QPhongMaterial> 

Scene::Scene(QWidget *parent) 
    : QWidget(parent) 
{ 
    auto view = new Qt3DExtras::Qt3DWindow(); 

    // create a container for Qt3DWindow 
    container = createWindowContainer(view,this); 

    // background color 
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x575757))); 

    // Root entity 
    auto rootEntity = new Qt3DCore::QEntity(); 

    // Camera 
    auto camera = new Camera(rootEntity,view); 
    auto cameraEntity = view->camera(); 

    cameraEntity->setPosition(QVector3D(0, 0, 50.0f)); 
    cameraEntity->setUpVector(QVector3D(0, 1, 0)); 
    cameraEntity->setViewCenter(QVector3D(0, 0, 0)); 

    // Cuboid 
    auto cuboidMesh = new Qt3DExtras::QCuboidMesh(); 

    // CuboidMesh Transform 
    auto cuboidTransform = new Qt3DCore::QTransform(); 
    cuboidTransform->setScale(10.0f); 
    cuboidTransform->setTranslation(QVector3D(0.0f, 0.0f, 0.0f)); 
    cuboidTransform->setRotation(QQuaternion(1,1.5,1,0).normalized()); 

    auto cuboidMaterial = new Qt3DExtras::QPhongMaterial(); 
    cuboidMaterial->setDiffuse(QColor(QRgb(0x005FFF))); 

    // assamble entity 
    auto cuboidEntity = new Qt3DCore::QEntity(rootEntity); 
    cuboidEntity->addComponent(cuboidMesh); 
    cuboidEntity->addComponent(cuboidMaterial); 
    cuboidEntity->addComponent(cuboidTransform); 

    // Set root object of the scene 
    view->setRootEntity(rootEntity); 
} 

void 
Scene::resizeView(QSize size) 
{ 
    container->resize(size); 
} 

void 
Scene::resizeEvent (QResizeEvent * /*event*/) 
{ 
    resizeView(this->size()); 
} 
Các vấn đề liên quan