当前位置: 首页 > news >正文

QT(c++)开发自学笔记:4.Qt 3D简易实现

一、一个简单的例子

        显示鼠标可以拖动的3D正方体

       CMakeLists.txt完整代码如下:

cmake_minimum_required(VERSION 3.16)project(My3DCube LANGUAGES CXX)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 自动运行 moc、uic、rcc
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)# 查找 Qt6 组件(必须包含 3D 相关模块)
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets 3DCore 3DRender 3DInput 3DExtras)# 添加可执行文件
add_executable(${PROJECT_NAME}main.cppdialog.cppdialog.hdialog.ui
)# 链接 Qt 模块
target_link_libraries(${PROJECT_NAME} PRIVATEQt6::CoreQt6::GuiQt6::WidgetsQt6::3DCoreQt6::3DRenderQt6::3DInputQt6::3DExtras
)# 可选:安装规则
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}BUNDLE DESTINATION .RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

 逐行分析如下:

cmake_minimum_required(VERSION 3.16)
        作用:指定 CMake 的最低版本要求为 3.16,确保构建系统支持所需的 CMake 功能。足以支持 Qt 6 和 Qt 3D 的构建需求。

project(My3DCube LANGUAGES CXX)

  • 作用:定义项目名称为 My3DCube,指定使用 C++ 语言。

set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)

  • 作用:设置 C++ 标准为 C++17,并要求强制使用该标准。

set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON)

  • 作用
    • CMAKE_AUTOMOC:启用 Qt 的元对象编译器(moc),自动处理包含 Q_OBJECT 宏的头文件(如 dialog.h)。
    • CMAKE_AUTOUIC:自动处理 Qt Designer 生成的 .ui 文件(如 dialog.ui),将其转换为 C++ 代码。
    • CMAKE_AUTORCC:自动处理 Qt 资源文件(.qrc),但当前项目未使用资源文件。
      • dialog.ui 需要 CMAKE_AUTOUIC 来生成 UI 代码。
      • dialog.h 包含 Q_OBJECT 宏(因为 Dialog 继承 QDialog),需要 CMAKE_AUTOMOC
      • 当前没有 .qrc 文件,CMAKE_AUTORCC 可保留以支持未来扩展。

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

  • 作用:查找 Qt6 库,并要求包含以下模块:
    • Core:Qt 的核心功能(如 QObjectQString)。
    • Gui:GUI 相关功能(如 QColorQWidget)。
    • Widgets:Widget 系统(如 QDialogQVBoxLayout)。
    • 3DCore:Qt 3D 核心模块(如 QEntityQTransform)。
    • 3DRender:Qt 3D 渲染模块(如 QCameraQMaterial)。
    • 3DInput:Qt 3D 输入模块(如 QOrbitCameraController 的输入处理)。
    • 3DExtras:Qt 3D 扩展模块(如 QCuboidMeshQPhongMaterialQOrbitCameraController)。
      • 项目使用 Qt3DExtras::Qt3DWindowQt3DCore::QEntityQt3DExtras::QCuboidMeshQt3DExtras::QPhongMaterial 等,依赖 3DCore3DRender 和 3DExtras
      • QOrbitCameraController 需要 3DInput 和 3DExtras
      • QDialog 和 QVBoxLayout 需要 Widgets
      • QColor 需要 Gui

add_executable(${PROJECT_NAME} main.cpp dialog.cpp dialog.h dialog.ui )

  • 作用:定义可执行目标 My3DCube,包含源文件 main.cppdialog.cppdialog.h 和 UI 文件 dialog.ui
    • main.cpp 启动应用程序,通常创建 QApplication 和 Dialog 实例。
    • dialog.cpp 和 dialog.h 实现 3D 场景逻辑(立方体、相机、背景色等)。
    • dialog.ui 定义 UI 布局(包含 qt3dContainer 用于嵌入 Qt3DWindow)。
    • 文件列表完整,符合项目结构。

target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::3DCore Qt6::3DRender Qt6::3DInput Qt6::3DExtras )

  • 作用:将可执行目标 My3DCube 链接到 Qt6 的指定模块,确保程序能访问所需库。
  • 链接的模块与 find_package 一致,涵盖了所有 Qt 3D 和 Widget 功能,确保 QPhongMaterialQCuboidMeshQOrbitCameraController 等类的可用性。

include(GNUInstallDirs) install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION . RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )

  • 作用
    • include(GNUInstallDirs):定义标准安装路径(如 binlib)。
    • install:指定安装规则,将可执行文件安装到 CMAKE_INSTALL_BINDIR(通常为 bin 目录)。

dialog.h代码如下:

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DInput/QMouseHandler>
#include <QOrbitCameraController>
#include <Qt3DRender/QFrameGraphNode> // 支持 frame graph 相关类
#include <Qt3DExtras/QForwardRenderer> // 显式包含 QForwardRenderer
#include <QVBoxLayout> // 支持布局操作QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:explicit Dialog(QWidget *parent = nullptr);~Dialog();private:Ui::Dialog *ui;Qt3DExtras::Qt3DWindow *m_view;QWidget *m_container;Qt3DCore::QEntity *m_rootEntity;Qt3DCore::QEntity *m_cubeEntity;void setup3DScene();
};#endif // DIALOG_H

dialog.cpp如下:

#include "dialog.h"
#include "ui_dialog.h"#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DRender/QCamera>
#include <Qt3DCore/QTransform>Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog),m_view(nullptr),m_container(nullptr),m_rootEntity(nullptr),m_cubeEntity(nullptr)
{ui->setupUi(this);// 创建 Qt3D 窗口m_view = new Qt3DExtras::Qt3DWindow();// 修改背景色为白色m_view->defaultFrameGraph()->setClearColor(QColor("#FFFFFF"));// 创建容器 widget 并嵌入到 UI 中m_container = QWidget::createWindowContainer(m_view, ui->qt3dContainer);// 检查 qt3dContainer 是否有布局,如果没有则添加一个if (!ui->qt3dContainer->layout()) {QVBoxLayout *layout = new QVBoxLayout(ui->qt3dContainer);layout->addWidget(m_container);} else {ui->qt3dContainer->layout()->addWidget(m_container);}setup3DScene();
}Dialog::~Dialog()
{delete ui;
}void Dialog::setup3DScene()
{// 根实体m_rootEntity = new Qt3DCore::QEntity();// === 创建正方体 ===m_cubeEntity = new Qt3DCore::QEntity(m_rootEntity);// 几何体:正方体auto *cubeMesh = new Qt3DExtras::QCuboidMesh();cubeMesh->setXExtent(2.0f);cubeMesh->setYExtent(2.0f);cubeMesh->setZExtent(2.0f);// 材质:浅蓝色auto *material = new Qt3DExtras::QPhongMaterial();material->setDiffuse(QColor("#6495ED")); // 浅蓝色(Cornflower Blue)material->setAmbient(QColor("#6495ED")); // 设置环境光为相同浅蓝色,确保无光源时可见// 不设置高光(specular)和光泽(shininess),因为没有光源// 变换:初始位置和旋转auto *transform = new Qt3DCore::QTransform();transform->setScale(1.0f);transform->setTranslation(QVector3D(0.0f, 0.0f, 0.0f));// 添加组件m_cubeEntity->addComponent(cubeMesh);m_cubeEntity->addComponent(material);m_cubeEntity->addComponent(transform);// === 相机 ===auto *camera = m_view->camera();camera->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f, 1000.0f);camera->setPosition(QVector3D(0, 0, 10.0f));camera->setViewCenter(QVector3D(0, 0, 0));// === 轨道相机控制器(支持鼠标拖动旋转、滚轮缩放)===auto *camController = new Qt3DExtras::QOrbitCameraController(m_rootEntity);camController->setLinearSpeed(50.0f);camController->setLookSpeed(180.0f);camController->setCamera(camera);// 设置根实体m_view->setRootEntity(m_rootEntity);
}

main.cpp如下:


#include <QApplication>
#include "dialog.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);Dialog w;w.setWindowTitle("3D 正方体 - 鼠标拖动旋转");w.resize(800, 600);w.show();return a.exec();
}

dailog.ui中只需要拖入一个Widget框,然后给它命名为qt3dContainer就行,这个框就是3D模型显示范围,可以适当拉大一点

运行结果如下:

http://www.dtcms.com/a/531881.html

相关文章:

  • Vue3 自定义事件
  • 上海住房和城乡建设厅网站个人备案网站可以做产品推广
  • Android OpenGLES视频剪辑示例源码
  • 做淘宝客导购网站推广wordpress 明星
  • WebForms 页面
  • Leetcode 39
  • 【STM32项目开源】基于STM32的智能水质检测系统
  • 设计模式-迭代器模式(Iterator)
  • GitHub等平台形成的开源文化正在重塑天热e
  • 做网站需要用什么开发软件有哪些制作视频的软件
  • github中获得Personal Access Token
  • 从RDPDD!DrvEscape到RDPWD!ShareClass::UPSendOrders
  • RiPro数据转换CeoMax插件
  • IA复习笔记4 路由
  • 邯郸手机网站建设服务常见的网络推广工具
  • NTRU 加密系统原理及示例:NTRU、CTRU以及ITRU
  • k8s高频面试题汇总
  • 一篇文章理解LRC校验:
  • 石家庄免费网站建设百度收录入口提交查询
  • 专业提供网站建设服务培训学校 网站费用
  • 找做网站公司需要注意什么条件国外网站建设什么价格
  • 阮一峰《TypeScript 教程》学习笔记——tsconfig.json 文件
  • python如何做声音识别
  • 解决Docker磁盘空间不足导致MySQL启动失败
  • 【微服务组件】Springboot结合Dubbo实现RPC调用
  • One-Shot Federated Learning with Classifier-FreeDiffusion Models
  • powershell终端在ide里默认位置不对
  • 探索Linux进程:从理论到实践
  • 正则化机制解析:L2 的约束逻辑与 L1 的特征选择
  • 股票与期货战法理论发展路径