Qt3D--箭头示例

程序运行效果图:

以上效果图使用Qt原生控件,没有对控件进行QSS设置,下面有源码,你可以在mainwindow.cpp中对控件进行样式设置。

该工程用的是Qt6进行开发 使用C++语言 用CMake进行构建工程。

代码讲解可能不太详细或者有兴趣再加,首先了解Qt3D进行开发时,相关类的作用。该工程为你提供参考示例。

箭头讲解:

箭头源码:

arrowentity.h

cpp 复制代码
#ifndef ARROWENTITY_H
#define ARROWENTITY_H

#include <QObject>
#include <QWidget>
#include <QDebug>
#include <QTimer>
#include <QColor>
#include <QColorDialog>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QPointLight>
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QCylinderMesh>
#include <Qt3DExtras/QConeMesh>

#include <QVector3D>

struct ArrowSize{

    double cyLen_ = 1;
    double conLen_ = 1;
    double cyR_ = 1;
    double conR_ = 1;
public:
    ArrowSize()
    {

    }
    ArrowSize(double cyLen,double cyR,double conLen,double conR)
        :cyLen_(cyLen),cyR_(cyR),conLen_(conLen),conR_(conR)
    {

    }
};

class ArrowEntity : public Qt3DCore::QEntity
{
    Q_OBJECT
public:
    explicit ArrowEntity(Qt3DCore::QEntity* parent = nullptr);
    ~ArrowEntity(){}

    //获取跟实体
    Qt3DCore::QEntity* getRootEntity();

    //重置视图按钮
    void ResetView();

    //设置箭头位置函数 ,输入位置QVector3D
    void setArrowPosition(QVector3D& pos);
    //设置柱体 圆锥 的长度与最大半径 ,输入参数是大于0的double数值
    void setArrowLenAndRot(ArrowSize& sz);

    //设置圆柱体颜色 位置
    void setCylinderColorSelected(QColor& col);

    //设置圆锥体颜色 位置
    void setConeColorSelected(QColor& col);
    //获取圆柱颜色
    QColor getCyColor();
    //获取圆锥颜色
    QColor getConColor();
private:
    //禁用拷贝构造 和 赋值重载
    ArrowEntity(ArrowEntity& arrow)=delete;
    ArrowEntity& operator=(ArrowEntity& arrow)=delete;

    //创建 圆柱体 圆锥体实体
    void createCylinderAndConeEntity();

    //物体自动旋转
    void updateRotation();


public slots:

    //自动旋转 -- 用定时器控制
    void onAutoRotateTimer(const QVector3D &eulerAngles);

    //通过滑杆控件 -- 控制物体旋转 x y z 速度
    void onXRotationChanged(int angle);
    void onYRotationChanged(int angle);
    void onZRotationChanged(int angle);
    void onRotationSpeedChanged(int speed);

    void onXDirect(const QString& x);
    void onYDirect(const QString& y);
    void onZDirect(const QString& z);

private:
    //颜色
    QColor cylinderColor;       //圆柱体颜色
    QColor coneColor;           //圆锥体颜色

    //长度 半径
    ArrowSize entitySz;//该对象可以设置 圆柱圆锥的长度半径

    //圆柱体 圆锥体实体 根实体
    // Qt3DCore::QEntity *rootEntity;              // 根实体
    Qt3DCore::QEntity *rootNextEntity;          //部分跟实体
    Qt3DCore::QEntity *cylinderEntity;          // 圆柱体实体
    Qt3DCore::QEntity *coneEntity;              // 圆锥体实体

    //物体旋转  x y z 速度
    QVector3D xyzRotation;
    int rotationSpeed = 2;

    //物体坐标
    QVector3D xyzPos = {0,0,0};

    //网格
    Qt3DExtras::QCylinderMesh* cylinder;
    Qt3DExtras::QConeMesh* cone;

    //材质 变换
    Qt3DCore::QTransform *partTransform;       // 模型局部变换--不包含上一层的任何实体
    Qt3DCore::QTransform *modelTransform;       // 模型整体变换
    Qt3DCore::QTransform *cylinderTransform;    // 圆柱体变换
    Qt3DCore::QTransform *coneTransform;        // 圆锥体变换
    Qt3DExtras::QPhongMaterial *cylinderMaterial; // 圆柱体材质
    Qt3DExtras::QPhongMaterial *coneMaterial;     // 圆锥体材质

    //自动旋转定时器
    QTimer* autoRotateTimer;
};

#endif // ARROWENTITY_H

arrowentity.cpp

cpp 复制代码
#include "arrowentity.h"

#include <QSize>
#include <QScreen>


ArrowEntity::ArrowEntity(Qt3DCore::QEntity* parent)
    :Qt3DCore::QEntity(parent)
    ,cylinderEntity(nullptr)
    ,coneEntity(nullptr)
    ,modelTransform(nullptr)
    ,cylinderTransform(nullptr)
    ,coneTransform(nullptr)
    ,cylinderMaterial(nullptr)
    ,coneMaterial(nullptr)
{
    qDebug()<<"arrowentity";
    ArrowSize sz(2.0,0.5,3,1);
    entitySz = sz;
    createCylinderAndConeEntity();
}

Qt3DCore::QEntity *ArrowEntity::getRootEntity()
{
    return this;
}

void ArrowEntity::createCylinderAndConeEntity()
{
    //创建模型整体变换
    modelTransform = new Qt3DCore::QTransform();
    this->addComponent(modelTransform);

    //创建光源
    // Qt3DRender::QPointLight* light = new Qt3DRender::QPointLight();
    Qt3DRender::QDirectionalLight* light = new Qt3DRender::QDirectionalLight();
    // light->setIntensity(1.0f);
    // light->setColor("white");
    light->setColor(QColor(Qt::white));
    light->setIntensity(1.0f);
    light->setWorldDirection(QVector3D(-1, -1, -1));
    Qt3DCore::QTransform* lightTrans = new Qt3DCore::QTransform();
    lightTrans->setTranslation(QVector3D(10,10,20));//光源位置

    //光实体
    Qt3DCore::QEntity* lightEntity = new Qt3DCore::QEntity(this);
    lightEntity->addComponent(light);
    lightEntity->addComponent(lightTrans);

    rootNextEntity = new Qt3DCore::QEntity(this);
    partTransform = new Qt3DCore::QTransform();
    rootNextEntity->addComponent(partTransform);
    //创建圆柱实体
    cylinderEntity = new Qt3DCore::QEntity(rootNextEntity);
    //创建网格
    cylinder = new Qt3DExtras::QCylinderMesh();
    // cylinder->setLength(5.0f);  //长度
    // cylinder->setRadius(0.8f);  //半径
    cylinder->setLength(entitySz.cyLen_);  //长度
    cylinder->setRadius(entitySz.cyR_);  //半径
    cylinder->setRings(100);    //环数
    cylinder->setSlices(20);    //切片数
    //创建位置
    cylinderTransform = new Qt3DCore::QTransform();
    cylinderTransform->setTranslation(QVector3D(0, entitySz.cyLen_/2.0, 0));
    //创建材质
    cylinderMaterial = new Qt3DExtras::QPhongMaterial();
    cylinderMaterial->setDiffuse(QColor(QRgb(0x0055ff)));
    cylinderEntity->addComponent(cylinder);
    cylinderEntity->addComponent(cylinderTransform);
    cylinderEntity->addComponent(cylinderMaterial);

    //创建圆锥实体
    coneEntity = new Qt3DCore::QEntity(rootNextEntity);

    cone = new Qt3DExtras::QConeMesh();
    // cone->setRings(8);   //半径
    // cone->setLength(3.0f);  //长度
    cone->setBottomRadius(entitySz.conR_);   //半径
    cone->setLength(entitySz.conLen_);  //长度
    cone->setSlices(20);    //切片
    cone->setRings(200);    //环数
    //位置
    coneTransform = new Qt3DCore::QTransform();
    coneTransform->setTranslation(QVector3D(0, entitySz.cyLen_ + entitySz.conLen_/2.0, 0));
    //创建材质
    coneMaterial = new Qt3DExtras::QPhongMaterial();
    coneMaterial->setDiffuse(QColor(QRgb(0xff5500)));

    coneEntity->addComponent(cone);
    coneEntity->addComponent(coneTransform);
    coneEntity->addComponent(coneMaterial);

}

void ArrowEntity::updateRotation()
{
    // 设置模型的旋转,使用四元数避免万向锁问题
    modelTransform->setRotation(QQuaternion::fromEulerAngles(xyzRotation));
}

void ArrowEntity::setCylinderColorSelected(QColor &col)
{
    cylinderMaterial->setDiffuse(col);
}

void ArrowEntity::setConeColorSelected(QColor &col)
{
    coneMaterial->setDiffuse(col);
}

// void ArrowEntity::onCylinderColorSelected()
// {
//     // QWidget* parentWidget = new QWidget();  // 创建临时QWidget
//     // QColor color = QColorDialog::getColor(cylinderMaterial->diffuse(), parentWidget, "选择圆柱体颜色");
//     // if (color.isValid()) {
//     //     cylinderMaterial->setDiffuse(color);
//     // }
//     // delete parentWidget;
//     cylinderMaterial->setDiffuse(color);
// }

// void ArrowEntity::onConeColorSelected()
// {
//     // QWidget* parentWidget = new QWidget();  // 创建临时QWidget
//     // QColor color = QColorDialog::getColor(coneMaterial->diffuse(), parentWidget, "选择圆锥体颜色");
//     // if (color.isValid()) {
//     //     coneMaterial->setDiffuse(color);
//     // }
//     // delete parentWidget;
//     coneMaterial->setDiffuse(color);
// }

void ArrowEntity::onAutoRotateTimer(const QVector3D &eulerAngles)
{
    // // 初始化自动旋转定时器
    // autoRotateTimer = new QTimer(this);
    // connect(autoRotateTimer, &QTimer::timeout, [this]() {
    //     // 自动旋转逻辑 - 同时绕三个轴旋转,速度由rotationSpeed控制
    //     xRotation += 0.5f * rotationSpeed;
    //     yRotation += 0.3f * rotationSpeed;
    //     zRotation += 0.2f * rotationSpeed;

    //     // 确保角度在0-360之间
    //     if (xRotation >= 360) xRotation -= 360;
    //     if (yRotation >= 360) yRotation -= 360;
    //     if (zRotation >= 360) zRotation -= 360;
    // QVector3D xyzRotation(xRotation,yRotation,zRotation);
    // //     updateRotation();

    //     // 更新滑块位置
    //     QSlider* xSlider = findChild<QSlider*>();
    //     if (xSlider) xSlider->setValue(static_cast<int>(xRotation));
    // });
}

void ArrowEntity::onXRotationChanged(int angle)
{
    xyzRotation.setX(angle);
    updateRotation();
}

void ArrowEntity::onYRotationChanged(int angle)
{
    xyzRotation.setY(angle);
    updateRotation();
}

void ArrowEntity::onZRotationChanged(int angle)
{
    xyzRotation.setZ(angle);
    updateRotation();
}

void ArrowEntity::onRotationSpeedChanged(int speed)
{
    rotationSpeed = speed;
}

void ArrowEntity::onXDirect(const QString &x)
{
    qDebug()<<"ArrowEntity::onXDirect";
    // cylinderTransform->setRotation(QQuaternion::fromEulerAngles(QVector3D(x.toDouble(),1,1)));
    // coneTransform->setRotation(QQuaternion::fromEulerAngles(QVector3D(x.toDouble(),1,1)));
    partTransform->setRotation(QQuaternion::fromEulerAngles(QVector3D(x.toDouble(),1,1)));
}

void ArrowEntity::onYDirect(const QString &y)
{
    partTransform->setRotation(QQuaternion::fromEulerAngles(QVector3D(1,y.toDouble(),1)));
}

void ArrowEntity::onZDirect(const QString &z)
{
    partTransform->setRotation(QQuaternion::fromEulerAngles(QVector3D(1,1,z.toDouble())));
}

void ArrowEntity::ResetView()
{
    xyzRotation.setX(0);
    xyzRotation.setY(0);
    xyzRotation.setZ(0);
    updateRotation();
}

void ArrowEntity::setArrowPosition(QVector3D &pos)
{
    xyzPos = pos;
    modelTransform->setTranslation(xyzPos);
}

void ArrowEntity::setArrowLenAndRot(ArrowSize& sz)
{
    if(sz.cyLen_>0)
    {
        entitySz.cyLen_ = sz.cyLen_;
    }
    if(sz.conLen_>0)
    {
        entitySz.conLen_ = sz.conLen_;
    }
    if(sz.cyR_>0)
    {
        entitySz.cyR_ = sz.cyR_;
    }
    if(sz.conR_>0)
    {
        entitySz.conR_ = sz.conR_;
    }
    if(sz.cyLen_>0||sz.conLen_>0||sz.cyR_>0||sz.conR_>0)
    {
        // entitySz = sz;
        cylinder->setLength(entitySz.cyLen_);  //长度
        cylinder->setRadius(entitySz.cyR_);  //半径
        cylinder->setRings(100); // 保持网格精度一致
        cylinder->setSlices(20);
        // cylinder->setEnabled(false);
        // cylinderTransform->setTranslation(QVector3D(0,0,0)+xyzPos);
        cylinderTransform->setTranslation(QVector3D(0,entitySz.cyLen_/2.0,0));
        cone->setBottomRadius(entitySz.conR_);   //半径
        cone->setLength(entitySz.conLen_);  //长度
        cone->setRings(200);                   // 保持网格精度
        cone->setSlices(20);
        // qDebug()<<entitySz.cyLen_/2.0 + entitySz.conLen_/2.0;
        coneTransform->setTranslation(QVector3D(0,entitySz.cyLen_/*/2.0*/ + entitySz.conLen_/2.0,0));
    }
}

QColor ArrowEntity::getCyColor()
{
    return cylinderMaterial->diffuse();
}
QColor ArrowEntity::getConColor()
{
    return coneMaterial->diffuse();
}

坐标轴讲解:

坐标轴源码:

coordinateaxis.h

cpp 复制代码
#ifndef COORDINATEAXIS_H
#define COORDINATEAXIS_H

#include <QWidget>
#include <QObject>
#include <Qt3DCore/QEntity>
#include <Qt3DExtras/QCylinderMesh>
#include <Qt3DExtras/QConeMesh>
#include <QColor>
#include <QColorDialog>
#include <QSize>
#include <QVector3D>
#include <QDebug>


struct AxisSize{

    double cyLen_ = 1;
    double conLen_ = 1;
    double cyR_ = 1;
    double conR_ = 1;
public:
    AxisSize()
    {

    }
    AxisSize(double cyLen,double cyR,double conLen,double conR)
        :cyLen_(cyLen),cyR_(cyR),conLen_(conLen),conR_(conR)
    {

    }
    // AxisSize& operator=(AxisSize& axSz)
    // {
    //     if(*this != axSz)
    //     {
    //         conLen_ = axSz.conLen_;
    //         conR_ = axSz.conR_;
    //         cyLen_ = axSz.cyLen_;
    //         cyR_ = axSz.cyR_;
    //     }
    //     return *this;
    // }
    // bool operator!=(AxisSize& axSz)
    // {
    //     return *this == axSz;
    // }
    // bool operator==(AxisSize& axSz)
    // {
    //     if(conLen_ == axSz.conLen_&&conR_ == axSz.conR_&&
    //         cyLen_ == axSz.cyLen_&&cyR_ == axSz.cyR_)
    //         return true;
    //     else
    //         return false;
    // }
};

class CoordinateAxis : public Qt3DCore::QEntity
{
    Q_OBJECT
public:
    CoordinateAxis(Qt3DCore::QEntity* parent = nullptr)
        :Qt3DCore::QEntity(parent)
        ,m_rootEntity(new Qt3DCore::QEntity(parent))
    {

        AxisSize ax(7.0,0.05,0.5,0.1);
        axSz = ax;
        createAxis(7.0f);
    }
    void createAxis(double length);
    Qt3DCore::QEntity* getAxisEntity() const;
private:
    Qt3DCore::QEntity* createSingleAxis(double length, const QVector3D& direction,const QColor& color);
private:
    Qt3DCore::QEntity* m_rootEntity = nullptr;
    double m_axisLength;

    AxisSize axSz;
};

#endif // COORDINATEAXIS_H

coordinateaxis.cpp

cpp 复制代码
#include "coordinateaxis.h"

#include <Qt3DExtras/QCylinderMesh>
#include <Qt3DExtras/QConeMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DCore/QTransform>



void CoordinateAxis::createAxis(double length)
{
    m_axisLength = length;

    // 创建X轴(红色)
    createSingleAxis(length, QVector3D(1, 0, 0), QColor(255, 0, 0));

    // 创建Y轴(绿色)
    createSingleAxis(length, QVector3D(0, 1, 0), QColor(0, 255, 0));

    // 创建Z轴(蓝色)
    createSingleAxis(length, QVector3D(0, 0, 1), QColor(0, 0, 255));
}

Qt3DCore::QEntity* CoordinateAxis::getAxisEntity() const
{
    return m_rootEntity;
}


Qt3DCore::QEntity* CoordinateAxis::createSingleAxis(double length, const QVector3D& direction, const QColor& color)
{
    // 创建轴实体
    Qt3DCore::QEntity* axis = new Qt3DCore::QEntity(m_rootEntity);
    Qt3DCore::QEntity* axis1 = new Qt3DCore::QEntity(m_rootEntity);

    // 创建圆柱(轴主体)
    Qt3DExtras::QCylinderMesh* cylinderMesh = new Qt3DExtras::QCylinderMesh(axis);
    cylinderMesh->setRadius(axSz.cyR_);
    cylinderMesh->setLength(axSz.cyLen_);
    cylinderMesh->setSlices(20);    // 切片数
    cylinderMesh->setRings(200);    // 环数

    // 计算圆柱变换(位置和旋转)
    Qt3DCore::QTransform* cylinderTrans = new Qt3DCore::QTransform(axis);

    if (direction == QVector3D(1, 0, 0)) {
        // X轴:绕Z轴旋转90°,使圆柱体沿X轴正方向延伸
        cylinderTrans->setRotation(QQuaternion::fromEulerAngles(0, 0, -90));
    } else if (direction == QVector3D(0, 0, 1)) {
        // Z轴:绕X轴旋转90°,使圆柱体沿Z轴延伸
        cylinderTrans->setRotation(QQuaternion::fromEulerAngles(90, 0, 0));
    }
    // Y轴无需旋转(默认沿Y轴延伸)

    // 设置平移,使轴从原点开始到length长度
    cylinderTrans->setTranslation(direction * (float)(length / 2.0));

    // 创建材质
    Qt3DExtras::QPhongMaterial* material = new Qt3DExtras::QPhongMaterial(axis1);
    material->setDiffuse(color);

    // 创建圆锥(轴端点)
    Qt3DExtras::QConeMesh* coneMesh = new Qt3DExtras::QConeMesh(axis1);
    coneMesh->setBottomRadius(axSz.conR_);
    coneMesh->setLength(axSz.conLen_); // 锥体长
    coneMesh->setSlices(20);
    coneMesh->setRings(200);

    // 计算圆锥变换
    Qt3DCore::QTransform* coneTrans = new Qt3DCore::QTransform(axis1);
    coneTrans->setRotation(cylinderTrans->rotation()); // 与圆柱同方向

    // 圆锥位置:轴末端 + 圆锥长度的一半(使圆锥尖端朝外)
    // 关键修复:确保方向向量正确指向正方向
    coneTrans->setTranslation(direction * (float)length + direction * axSz.conLen_/2.0);

    // 添加组件到轴实体(关键修复:使用axis->addComponent)
    axis->addComponent(material);
    axis->addComponent(cylinderMesh);
    axis->addComponent(cylinderTrans);
    axis1->addComponent(coneMesh);
    axis1->addComponent(material);
    axis1->addComponent(coneTrans);

    return axis;
}

// Qt3DCore::QEntity* CoordinateAxis::createSingleAxis(double length,const QVector3D& direction,const QColor& color)
// {
//     // 创建轴实体
//     Qt3DCore::QEntity* axis = new Qt3DCore::QEntity(m_rootEntity);

//     // 创建圆柱(轴主体)
//     Qt3DExtras::QCylinderMesh* cylinderMesh = new Qt3DExtras::QCylinderMesh(axis);
//     cylinderMesh->setRadius(0.05f);
//     cylinderMesh->setLength(length);
//     cylinderMesh->setSlices(20);    //切片
//     cylinderMesh->setRings(200);    //环数

//     // 计算圆柱变换(位置和旋转)
//     Qt3DCore::QTransform* cylinderTrans = new Qt3DCore::QTransform(m_rootEntity);

//     if (direction == QVector3D(1, 0, 0)) {
//         // 修改前(错误):QQuaternion::fromEulerAngles(0, 180, 90)
//         // 修改后(正确):仅绕Z轴旋转90°,使圆柱体沿X轴延伸
//         cylinderTrans->setRotation(QQuaternion::fromEulerAngles(0, 0, 90));
//     } else if (direction == QVector3D(0, 0, 1)) {
//         // 保持正确:绕X轴旋转90°,使圆柱体沿Z轴延伸
//         cylinderTrans->setRotation(QQuaternion::fromEulerAngles(90, 0, 0));
//     }
//     // Y轴无需旋转(默认沿Y轴延伸),保持原逻辑

//     // 设置平移,使轴从原点开始
//     cylinderTrans->setTranslation(direction * (float)(length / 2.0));

//     // 创建材质
//     Qt3DExtras::QPhongMaterial* material = new Qt3DExtras::QPhongMaterial(m_rootEntity);
//     material->setDiffuse(color);

//     // 创建圆锥(轴端点)
//     Qt3DExtras::QConeMesh* coneMesh = new Qt3DExtras::QConeMesh();
//     coneMesh->setBottomRadius(0.3f);
//     coneMesh->setLength(1.0f); // 锥体长
//     coneMesh->setSlices(20);    //切片
//     coneMesh->setRings(200);    //环数

//     // 计算圆锥变换
//     Qt3DCore::QTransform* coneTrans = new Qt3DCore::QTransform();
//     coneTrans->setRotation(cylinderTrans->rotation()); // 与圆柱同方向
//     // 圆锥位置:轴末端 + 圆锥长度的一半(使圆锥尖端朝外)
//     coneTrans->setTranslation(direction * (float)(length) + direction * 0.5f);

//     // 添加组件到轴实体
//     addComponent(material);
//     addComponent(cylinderMesh);
//     addComponent(cylinderTrans);
//     // axis->addComponent(coneMesh);
//     // axis->addComponent(material);
//     // axis->addComponent(coneTrans);

//     return axis;
// }

实体管理类讲解:

实体管理类源码:

totalentity.h

cpp 复制代码
#ifndef TOTALENTITY_H
#define TOTALENTITY_H

#include <QWidget>
#include <QObject>
#include <QVector>
#include <QSize>
#include <Qt3DCore/QEntity>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/Qt3DWindow>
#include <QScreen>
#include <Qt3DExtras/QForwardRenderer>


class TotalEntity
{
public:
    TotalEntity();

    //创建场景
    void create3DScene();
    //创建摄像机
    void createCamera();
    //获取3D场景控件
    QWidget* get3DViewWidget();

    //获取对象实体类型
    template<class T>
    T* getEntityObject()
    {
        for (auto& entity : allEntity) {
            // 直接转换 "基类指针 entity(QEntity*)" 为 "派生类指针 T*(如 ArrowEntity*)"
            T* derivedEntity = dynamic_cast<T*>(entity);
            if (derivedEntity != nullptr) {
                return derivedEntity;
            }
        }
        return nullptr;
    }

private:
    //存储所有需要展示的对象实体
    QVector<Qt3DCore::QEntity*> allEntity;

    Qt3DCore::QEntity* m_rootEntity = nullptr;//祖宗跟实体
    Qt3DCore::QEntity* m_currentEntity = nullptr;//当前跟实体

    //窗口
    Qt3DExtras::Qt3DWindow *view = nullptr;               // 主3D视图
    Qt3DExtras::Qt3DWindow *previewView = nullptr;        // 预览3D视图

    //相机
    Qt3DRender::QCamera* camera = nullptr;
    Qt3DExtras::QOrbitCameraController *cameraController = nullptr; // 相机控制器

    //3D视图显示控件
    QWidget* Widget3D = nullptr;
};

#endif // TOTALENTITY_H

totalentity.cpp

cpp 复制代码
#include "totalentity.h"

#include "arrowentity.h"
#include "coordinateaxis.h"



TotalEntity::TotalEntity()
    :m_rootEntity(new Qt3DCore::QEntity())
{
    create3DScene();
    createCamera();
    ArrowEntity* arrow = new ArrowEntity(m_rootEntity);
    // ArrowSize sz = {1,1,3,3};
    // arrow->setArrowLenAndRot(sz);
    CoordinateAxis* axis = new CoordinateAxis();
    axis->getAxisEntity()->setParent(arrow->getRootEntity());

    CoordinateAxis* axis1 = new CoordinateAxis();
    axis1->getAxisEntity()->setParent(m_rootEntity);
    // axis->setEnabled(false);

    // QVector3D pos(-2,-2,3);
    // arrow->setArrowPosition(pos);

    allEntity.append(arrow);
    allEntity.append(axis);
}

void TotalEntity::create3DScene()
{
    if(view==nullptr)
    {
        //创建3D视图
        view = new Qt3DExtras::Qt3DWindow();
        view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));

        //创建容纳3D视图的widget
        Widget3D = QWidget::createWindowContainer(view);
        QSize screen = view->screen()->size();
        view->setMinimumSize(QSize(400,300));
        view->setMaximumSize(screen);

        //将跟实体设置到场景
        view->setRootEntity(m_rootEntity);
    }
}

void TotalEntity::createCamera()
{
    if(view!=nullptr)
    {
        //设置相机
        camera = view->camera();
        camera->lens()->setPerspectiveProjection(45.0f,16.0f/9.0f,1.0f,1000.0f);
        camera->setPosition(QVector3D(0,0,20));
        camera->setViewCenter(QVector3D(3,3,3));

        // 相机控制器 - 支持鼠标拖拽旋转、滚轮缩放
        cameraController = new Qt3DExtras::QOrbitCameraController(m_rootEntity);
        cameraController->setCamera(camera);
        cameraController->setLinearSpeed(50.0f);  // 平移速度
        cameraController->setLookSpeed(180.0f);   // 旋转速度


        //创建光源
        // Qt3DRender::QPointLight* light = new Qt3DRender::QPointLight();
        Qt3DRender::QDirectionalLight* light = new Qt3DRender::QDirectionalLight();
        // light->setIntensity(1.0f);
        // light->setColor("white");
        light->setColor(QColor(Qt::white));
        light->setIntensity(1.0f);
        light->setWorldDirection(QVector3D(-5, 1, 1));
        Qt3DCore::QTransform* lightTrans = new Qt3DCore::QTransform();
        lightTrans->setTranslation(QVector3D(10,10,20));//光源位置

        //光实体
        Qt3DCore::QEntity* lightEntity = new Qt3DCore::QEntity();
        lightEntity->addComponent(light);
        lightEntity->addComponent(lightTrans);
        lightEntity->setParent(camera);
    }
    else
    {
        qDebug()<<"view is nullptr,cannot create camera.";
    }
}

QWidget* TotalEntity::get3DViewWidget()
{
    return Widget3D?Widget3D:nullptr; //感觉多次一举 在调用的地方判断不就可以了
}

界面控件设置类:

界面控件设置类源码:

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWidget>
#include <QString>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QLayout>
#include <QPushButton>
#include <QCheckBox>
#include <QSlider>
#include <QLabel>
#include <QTimer>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QLineEdit>

#include "totalentity.h"
#include "arrowentity.h"
class ArrowEntity;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    //创建控制面板
    void createControlWidget();
    //对所有控件进行信号和槽的绑定
    void allSignalBindSlot();

public slots:
    //重置视图
    void onResetView();
    //是否自动旋转
    void onToggleAutoRotation(bool checked);
    //输入框
    void on_XSpinBox(int x);
    void on_YSpinBox(int y);
    void on_ZSpinBox(int z);
    void on_speedSpinBox(int speed);

    void on_XLineEdit(const QString& x);
    void on_YLineEdit(const QString& y);
    void on_ZLineEdit(const QString& z);
    void on_SpeedLineEdit(const QString& speed);

    //实体信息槽函数
    void on_xEdit(const QString& x);
    void on_yEdit(const QString& y);
    void on_zEdit(const QString& z);
    void on_cyEdit(const QString& cyLen);
    void on_cyREdit(const QString& cyR);
    void on_conEdit(const QString& conLen);
    void on_conREdit(const QString& conR);

    void onCylinderColorSelected();
    void onConeColorSelected();

    void onSetEntityVisible(int flag);

private:

    //需要嵌入到 view的QWidget控件
    QWidget* widget3DView = nullptr;

    TotalEntity* rootEntity = nullptr;

    //滑杆控件
    QSlider *xRotSlider = nullptr;
    QSlider *yRotSlider = nullptr;
    QSlider *zRotSlider = nullptr;
    QSlider *speedSlider = nullptr;

    //输入框
    QLineEdit* xSpinBox = nullptr;
    QLineEdit* ySpinBox = nullptr;
    QLineEdit* zSpinBox = nullptr;
    QLineEdit* speedSpinBox = nullptr;

    //属性半径 信息
    QLineEdit* xEdit = nullptr;
    QLineEdit* yEdit = nullptr;
    QLineEdit* zEdit = nullptr;
    QLineEdit* cyEdit = nullptr;
    QLineEdit* cyREdit = nullptr;
    QLineEdit* conEdit = nullptr;
    QLineEdit* conREdit = nullptr;

    QLineEdit* xArrDirEdit = nullptr;
    QLineEdit* yArrDirEdit = nullptr;
    QLineEdit* zArrDirEdit = nullptr;

    QVector3D entityPos;
    ArrowSize att;

    //单选框
    // QCheckBox *autoRotateCheckBox = nullptr;//有点多余
    QCheckBox *coordModeCheckBox = nullptr;

    //颜色选择按钮
    QPushButton *cylinderColorBtn = nullptr;
    QPushButton *coneColorBtn = nullptr;
    QPushButton *resetBtn = nullptr;

    //定时器
    QTimer* autoRotateTimer = nullptr;
};
#endif // MAINWINDOW_H

mainwindow..cpp

cpp 复制代码
#include "mainwindow.h"

#include "arrowentity.h"
#include "coordinateaxis.h"
class ArrowEntity;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    ,rootEntity(new TotalEntity())
{
    widget3DView = rootEntity->get3DViewWidget();
    createControlWidget();
    allSignalBindSlot();
}

MainWindow::~MainWindow() {}

void MainWindow::createControlWidget()
{
    // 创建控制面板
    QWidget *controlPanel = new QWidget();
    QVBoxLayout *controlLayout = new QVBoxLayout(controlPanel);

    // 添加标题
    QLabel *titleLabel = new QLabel("<h3>模型控制器</h3>");
    controlLayout->addWidget(titleLabel);

    // 旋转控制 - X轴
    QHBoxLayout *xRotLayout = new QHBoxLayout();
    xRotLayout->addWidget(new QLabel("X轴旋转:"));
    xRotSlider = new QSlider(Qt::Horizontal);
    xRotSlider->setRange(0, 360);
    xRotSlider->setValue(0);
    xRotLayout->addWidget(xRotSlider);
    // xSpinBox = new QDoubleSpinBox();
    // xSpinBox->setMaximum(360);
    // xSpinBox->setMinimum(0);
    xSpinBox = new QLineEdit();
    // 创建整数验证器,设置范围0-360
    QIntValidator *xvalidator = new QIntValidator(0, 360, xSpinBox);
    // 设置验证器到QLineEdit
    xSpinBox->setValidator(xvalidator);
    // 可选:设置输入提示
    xSpinBox->setPlaceholderText("0-360整数");
    xRotLayout->addWidget(xSpinBox);
    controlLayout->addLayout(xRotLayout);

    // 旋转控制 - Y轴
    QHBoxLayout *yRotLayout = new QHBoxLayout();
    yRotLayout->addWidget(new QLabel("Y轴旋转:"));
    yRotSlider = new QSlider(Qt::Horizontal);
    yRotSlider->setRange(0, 360);
    yRotSlider->setValue(0);
    yRotLayout->addWidget(yRotSlider);
    ySpinBox = new QLineEdit();
    // 创建整数验证器,设置范围0-360
    QIntValidator *yvalidator = new QIntValidator(0, 360, ySpinBox);
    // 设置验证器到QLineEdit
    ySpinBox->setValidator(yvalidator);
    // 可选:设置输入提示
    ySpinBox->setPlaceholderText("0-360整数");
    yRotLayout->addWidget(ySpinBox);
    controlLayout->addLayout(yRotLayout);

    // 旋转控制 - Z轴
    QHBoxLayout *zRotLayout = new QHBoxLayout();
    zRotLayout->addWidget(new QLabel("Z轴旋转:"));
    zRotSlider = new QSlider(Qt::Horizontal);
    zRotSlider->setRange(0, 360);
    zRotSlider->setValue(0);
    zRotLayout->addWidget(zRotSlider);
    zSpinBox = new QLineEdit();
    // 创建整数验证器,设置范围0-360
    QIntValidator *zvalidator = new QIntValidator(0, 360, zSpinBox);
    // 设置验证器到QLineEdit
    zSpinBox->setValidator(zvalidator);
    // 可选:设置输入提示
    zSpinBox->setPlaceholderText("0-360整数");
    zRotLayout->addWidget(zSpinBox);
    controlLayout->addLayout(zRotLayout);

    // // 旋转速度控制
    // QHBoxLayout *speedLayout = new QHBoxLayout();
    // speedLayout->addWidget(new QLabel("旋转速度:"));
    // speedSlider = new QSlider(Qt::Horizontal);
    // speedSlider->setRange(1, 10);
    // speedSlider->setValue(2);
    // speedLayout->addWidget(speedSlider);
    // speedSpinBox = new QLineEdit();
    // 创建整数验证器,设置范围0-360
    // QIntValidator *speedvalidator = new QIntValidator(0, 360, speedSpinBox);
    // // 设置验证器到QLineEdit
    // speedSpinBox->setValidator(speedvalidator);
    // // 可选:设置输入提示
    // speedSpinBox->setPlaceholderText("1-10整数");
    // speedLayout->addWidget(speedSpinBox);
    // controlLayout->addLayout(speedLayout);

    //设置实体的空间坐标系
    QWidget* posWidget = new QWidget(this);
    QGridLayout* posLayout = new QGridLayout(posWidget);
    QLabel* xlabel = new QLabel("X坐标:",this);
    xEdit = new QLineEdit(this);
    xEdit->setPlaceholderText("请输入数值");
    QLabel* ylabel = new QLabel("Y坐标:",this);
    yEdit = new QLineEdit(this);
    yEdit->setPlaceholderText("请输入数值");
    QLabel* zlabel = new QLabel("Z坐标:",this);
    zEdit = new QLineEdit(this);
    zEdit->setPlaceholderText("请输入数值");
    posLayout->addWidget(xlabel,0,0);
    posLayout->addWidget(xEdit,0,1);
    posLayout->addWidget(ylabel,1,0);
    posLayout->addWidget(yEdit,1,1);
    posLayout->addWidget(zlabel,2,0);
    posLayout->addWidget(zEdit,2,1);
    controlLayout->addWidget(posWidget);

    //设置圆柱 圆锥 长 半径
    QWidget* entityAttribute = new QWidget(this);
    QGridLayout* attLayout = new QGridLayout(entityAttribute);
    QLabel* cylabel = new QLabel("圆柱长度:",this);
    cyEdit = new QLineEdit(this);
    cyEdit->setPlaceholderText("请输入长度");
    QLabel* cyRlabel = new QLabel("圆柱半径:",this);
    cyREdit = new QLineEdit(this);
    cyREdit->setPlaceholderText("请输入半径");
    QLabel* conlabel = new QLabel("圆锥长度:",this);
    conEdit = new QLineEdit(this);
    conEdit->setPlaceholderText("请输入长度");
    QLabel* conRlabel = new QLabel("圆锥半径:",this);
    conREdit = new QLineEdit(this);
    conREdit->setPlaceholderText("请输入半径");
    attLayout->addWidget(cylabel,0,0);
    attLayout->addWidget(cyEdit,0,1);
    attLayout->addWidget(cyRlabel,0,2);
    attLayout->addWidget(cyREdit,0,3);
    attLayout->addWidget(conlabel,1,0);
    attLayout->addWidget(conEdit,1,1);
    attLayout->addWidget(conRlabel,1,2);
    attLayout->addWidget(conREdit,1,3);
    controlLayout->addWidget(entityAttribute);

    //设置箭头的朝向
    QWidget* arrowDirect = new QWidget(this);
    QGridLayout* arrowDirectLayout = new QGridLayout(arrowDirect);
    QLabel* xArrDirlabel = new QLabel("箭头X轴方向:",this);
    xArrDirEdit = new QLineEdit(this);
    xArrDirEdit->setPlaceholderText("请输入X长度");
    QLabel* yArrDirlabel = new QLabel("箭头Y轴方向:",this);
    yArrDirEdit = new QLineEdit(this);
    yArrDirEdit->setPlaceholderText("请输入Y长度");
    QLabel* zArrDirlabel = new QLabel("箭头Z轴方向:",this);
    zArrDirEdit = new QLineEdit(this);
    zArrDirEdit->setPlaceholderText("请输入Z长度");
    arrowDirectLayout->addWidget(xArrDirlabel,0,0);
    arrowDirectLayout->addWidget(xArrDirEdit,0,1);
    arrowDirectLayout->addWidget(yArrDirlabel,1,0);
    arrowDirectLayout->addWidget(yArrDirEdit,1,1);
    arrowDirectLayout->addWidget(zArrDirlabel,2,0);
    arrowDirectLayout->addWidget(zArrDirEdit,2,1);
    controlLayout->addWidget(arrowDirect);

    // // 自动旋转复选框
    // autoRotateCheckBox = new QCheckBox("自动旋转");
    // controlLayout->addWidget(autoRotateCheckBox);

    // 坐标系模式切换
    coordModeCheckBox = new QCheckBox("只显示坐标系");
    controlLayout->addWidget(coordModeCheckBox);

    // 颜色选择按钮 - 圆柱体
    cylinderColorBtn = new QPushButton("选择圆柱体颜色");
    controlLayout->addWidget(cylinderColorBtn);

    // 颜色选择按钮 - 圆锥体
    coneColorBtn = new QPushButton("选择圆锥体颜色");
    controlLayout->addWidget(coneColorBtn);

    // 重置按钮
    resetBtn = new QPushButton("重置视图");
    controlLayout->addWidget(resetBtn);

    // 添加伸缩项,使控件靠上显示
    controlLayout->addStretch();

    // 主布局 - 包含预览窗口
    QWidget *mainContainer = new QWidget();
    QVBoxLayout *mainContainerLayout = new QVBoxLayout(mainContainer);

    // // 预览窗口容器
    // QWidget *previewContainer = QWidget::createWindowContainer(previewView);
    // previewContainer->setFixedSize(200, 200); // 预览窗口大小

    //顶部布局 - 主视图和预览窗口
    QHBoxLayout *topLayout = new QHBoxLayout();
    topLayout->addWidget(widget3DView, 1);

    // // 预览窗口放在右上角
    // QVBoxLayout *previewLayout = new QVBoxLayout();
    // previewLayout->addStretch();
    // previewLayout->addWidget(previewContainer, 0, Qt::AlignRight);
    // topLayout->addLayout(previewLayout);

    mainContainerLayout->addLayout(topLayout);

    // 主布局
    QHBoxLayout *mainLayout = new QHBoxLayout();
    mainLayout->addWidget(controlPanel, 3);  // 控制面板占30%宽度
    mainLayout->addWidget(mainContainer, 7); // 3D视图占70%宽度


    // 主窗口设置
    QWidget *mainWidget = new QWidget();
    mainWidget->setLayout(mainLayout);
    setCentralWidget(mainWidget);
    setWindowTitle("Qt3D 坐标系演示");
    resize(1200, 800);
}

void MainWindow::allSignalBindSlot()
{
    //创建定时器
    autoRotateTimer = new QTimer();

    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow!=nullptr)
    {
        // 连接信号槽
        connect(xRotSlider, &QSlider::valueChanged, arrow, &ArrowEntity::onXRotationChanged);
        connect(yRotSlider, &QSlider::valueChanged, arrow, &ArrowEntity::onYRotationChanged);
        connect(zRotSlider, &QSlider::valueChanged, arrow, &ArrowEntity::onZRotationChanged);
        // connect(speedSlider, &QSlider::valueChanged, arrow, &ArrowEntity::onRotationSpeedChanged);
        connect(cylinderColorBtn, &QPushButton::clicked, this, &MainWindow::onCylinderColorSelected);
        connect(coneColorBtn, &QPushButton::clicked, this, &MainWindow::onConeColorSelected);
        connect(xArrDirEdit, &QLineEdit::textEdited, arrow, &ArrowEntity::onXDirect);
        connect(yArrDirEdit, &QLineEdit::textEdited, arrow, &ArrowEntity::onYDirect);
        connect(zArrDirEdit, &QLineEdit::textEdited, arrow, &ArrowEntity::onZDirect);
        connect(coordModeCheckBox, &QCheckBox::stateChanged, this, &MainWindow::onSetEntityVisible);
    }
    // connect(autoRotateCheckBox, &QCheckBox::toggled, this, &MainWindow::onToggleAutoRotation);
    connect(resetBtn, &QPushButton::clicked, this, &MainWindow::onResetView);

    //实体坐标 圆柱 圆锥半径 长度
    connect(xEdit,&QLineEdit::textEdited,this,&MainWindow::on_xEdit);
    connect(zEdit,&QLineEdit::textEdited,this,&MainWindow::on_yEdit);
    connect(yEdit,&QLineEdit::textEdited,this,&MainWindow::on_zEdit);
    connect(cyEdit,&QLineEdit::textEdited,this,&MainWindow::on_cyEdit);
    connect(cyREdit,&QLineEdit::textEdited,this,&MainWindow::on_cyREdit);
    connect(conEdit,&QLineEdit::textEdited,this,&MainWindow::on_conEdit);
    connect(conREdit,&QLineEdit::textEdited,this,&MainWindow::on_conREdit);

    //输入框
    connect(xSpinBox,&QLineEdit::textEdited,this,&MainWindow::on_XLineEdit);
    connect(ySpinBox,&QLineEdit::textEdited,this,&MainWindow::on_YLineEdit);
    connect(zSpinBox,&QLineEdit::textEdited,this,&MainWindow::on_ZLineEdit);
    // connect(speedSpinBox,&QLineEdit::textEdited,this,&MainWindow::on_SpeedLineEdit);

    connect(xRotSlider, &QSlider::valueChanged, this,&MainWindow::on_XSpinBox);
    connect(yRotSlider, &QSlider::valueChanged, this,&MainWindow::on_YSpinBox);
    connect(zRotSlider, &QSlider::valueChanged, this,&MainWindow::on_ZSpinBox);
    // connect(speedSlider, &QSlider::valueChanged, this,&MainWindow::on_speedSpinBox);
}

void MainWindow::onResetView()
{
    // 重置滑块
    QList<QSlider*> sliders = findChildren<QSlider*>();
    for (int i = 0; i < sliders.size() && i < 3; ++i) {
        sliders[i]->setValue(0);
    }

    // 停止自动旋转
    autoRotateTimer->stop();
    QCheckBox* autoRotateCheckBox = findChild<QCheckBox*>();
    if (autoRotateCheckBox) {
        autoRotateCheckBox->setChecked(false);
    }
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    arrow->ResetView();
}

void MainWindow::onToggleAutoRotation(bool checked)
{
    if (checked) {
        autoRotateTimer->start(50); // 每50毫秒更新一次
    } else {
        autoRotateTimer->stop();
    }
}

void MainWindow::on_XSpinBox(int x)
{
    if(sender()==xRotSlider)
        xSpinBox->setText(QString::number(x, 10));
    else if(sender()==xSpinBox)
        xRotSlider->setValue(x);
}

void MainWindow::on_YSpinBox(int y)
{
    if(sender()==yRotSlider)
        ySpinBox->setText(QString::number(y, 10));
    else if(sender()==ySpinBox)
        yRotSlider->setValue(y);
}

void MainWindow::on_ZSpinBox(int z)
{
    if(sender()==zRotSlider)
        zSpinBox->setText(QString::number(z, 10));
    else if(sender()==zSpinBox)
        zRotSlider->setValue(z);
}

void MainWindow::on_speedSpinBox(int speed)
{
    if(sender()==speedSlider)
        speedSpinBox->setText(QString::number(speed, 10));
    else if(sender()==speedSpinBox)
        speedSlider->setValue(speed);
}

void MainWindow::on_XLineEdit(const QString &x)
{
    xRotSlider->setValue(x.toInt());
}

void MainWindow::on_YLineEdit(const QString &y)
{
    yRotSlider->setValue(y.toInt());
}

void MainWindow::on_ZLineEdit(const QString &z)
{
    zRotSlider->setValue(z.toInt());
}

void MainWindow::on_SpeedLineEdit(const QString &speed)
{
    speedSlider->setValue(speed.toInt());
}

void MainWindow::on_xEdit(const QString &x)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    entityPos.setX(x.toDouble());
    arrow->setArrowPosition(entityPos);
}

void MainWindow::on_yEdit(const QString &y)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    entityPos.setY(y.toDouble());
    arrow->setArrowPosition(entityPos);
}

void MainWindow::on_zEdit(const QString &z)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    entityPos.setZ(z.toDouble());
    arrow->setArrowPosition(entityPos);
}

void MainWindow::on_cyEdit(const QString &cyLen)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        // return ;
    }
    att.cyLen_ = cyLen.toDouble();
    arrow->setArrowLenAndRot(att);
}

void MainWindow::on_cyREdit(const QString &cyR)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    att.cyR_ = cyR.toDouble();
    arrow->setArrowLenAndRot(att);
}

void MainWindow::on_conEdit(const QString &conLen)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    att.conLen_ = conLen.toDouble();
    arrow->setArrowLenAndRot(att);
}

void MainWindow::on_conREdit(const QString &conR)
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow==nullptr)
    {
        qDebug()<<"MainWindow::allSignalBindSlot:get class Failed.";
        return ;
    }
    att.conR_ = conR.toDouble();
    arrow->setArrowLenAndRot(att);
}

void MainWindow::onCylinderColorSelected()
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow!=nullptr)
    {
        QColor color = QColorDialog::getColor(arrow->getCyColor(), this, "选择圆柱体颜色");
        if (color.isValid()) {
            arrow->setCylinderColorSelected(color);
        }
    }
}

void MainWindow::onConeColorSelected()
{
    ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
    if(arrow!=nullptr)
    {
        QColor color = QColorDialog::getColor(arrow->getCyColor(), this, "选择圆锥体颜色");
        if (color.isValid()) {
            arrow->setConeColorSelected(color);
        }
    }
}

void MainWindow::onSetEntityVisible(int flag)
{
    if(Qt::Unchecked == flag)
    {
        ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
        if(arrow!=nullptr)
        {
            arrow->setEnabled(true);
        }
    }
    else if(Qt::Checked == flag)
    {
        ArrowEntity* arrow = rootEntity->getEntityObject<ArrowEntity>();
        if(arrow!=nullptr)
        {
            arrow->setEnabled(false);
        }
    }
}

工程MakeList.txt

cpp 复制代码
cmake_minimum_required(VERSION 3.19)
project(3DModelArrow LANGUAGES CXX)

find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets
    3DCore
    3DRender
    3DExtras
    3DInput)

qt_standard_project_setup()

qt_add_executable(3DModelArrow
    WIN32 MACOSX_BUNDLE
    main.cpp
    mainwindow.cpp
    mainwindow.h
    arrowentity.h arrowentity.cpp

    coordinateaxis.h coordinateaxis.cpp
    totalentity.h totalentity.cpp
)

target_link_libraries(3DModelArrow
    PRIVATE
        Qt::Core
        Qt::Widgets
        Qt6::3DCore
        Qt6::3DRender
        Qt6::3DExtras
        Qt6::3DInput
)

include(GNUInstallDirs)

install(TARGETS 3DModelArrow
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_app_script(
    TARGET 3DModelArrow
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})
相关推荐
掘根2 小时前
【Qt】多线程
java·开发语言·qt
兰亭妙微3 小时前
兰亭妙微QT软件开发与UI设计协同:如何避免设计与实现脱节?
开发语言·qt·ui
深思慎考3 小时前
【新版】Elasticsearch 8.15.2 完整安装流程(Linux国内镜像提速版)
java·linux·c++·elasticsearch·jenkins·框架
sxtyjty4 小时前
ABC426G - Range Knapsack Query
c++·算法·分治
hetao17338374 小时前
2025-10-03 HETAO CSP-S复赛集训营模拟赛-002 总结 Ⅱ
c++·总结
ajassi20004 小时前
开源 C++ QT QML 开发(四)复杂控件--Listview
c++·qt·开源
Vect__4 小时前
二叉树实战笔记:结构、遍历、接口与 OJ 实战
数据结构·c++·算法
青草地溪水旁5 小时前
第六章:适配器模式 - 接口转换的艺术大师
c++·适配器模式
charlie1145141915 小时前
精读C++20设计模式——结构型设计模式:外观模式
c++·学习·设计模式·c++20·外观模式