[QML] 创建项目

张开发
2026/4/10 6:43:52 15 分钟阅读

分享文章

[QML] 创建项目
一.创建项目首先创建QML的hello world项目,此项目采用qt6.8,默认使用cmake构建系统。cmake_minimum_required(VERSION 3.16) project(SonicMusic VERSION 0.1 LANGUAGES CXX DESCRIPTION QML音乐播放器 HOMEPAGE_URL ) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(QT_QML_GENERATE_QMLLS_INI ON) find_package(Qt6 REQUIRED COMPONENTS Quick) qt_standard_project_setup(REQUIRES 6.8) qt_add_executable(appSonicMusic main.cpp ) qt_add_qml_module(appSonicMusic URI SonicMusic QML_FILES Main.qml ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # If you are developing for iOS or macOS you should consider setting an # explicit, fixed bundle identifier manually though. set_target_properties(appSonicMusic PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appSonicMusic MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) target_link_libraries(appSonicMusic PRIVATE Qt6::Quick ) install(TARGETS appSonicMusic BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )二 CMAKE详解cmake_minimum_required(VERSION 3.16) 设置cmake的最小版本2.1 project作用: 一般在项目最开头,自动创建“魔法变量”自动生成的变量作用举例 (基于你的项目)PROJECT_NAME当前项目的名字值为SonicMusicPROJECT_VERSION完整的版本号值为0.1PROJECT_SOURCE_DIR源代码所在的绝对路径比如/home/user/SonicMusicPROJECT_BINARY_DIR构建目录编译发生的地方比如/home/user/SonicMusic/buildCMAKE_PROJECT_NAME顶级项目的名字如果是单项目也是SonicMusicproject(MyQmlApp LANGUAGES CXX): 它不仅声明项目名称还能设置版本号、支持的编程语言并初始化相关变量。project(PROJECT_NAME[VERSION major[.minor[.patch[.tweak]]]][LANGUAGES language...][DESCRIPTION description][HOMEPAGE_URL url][CXX_STANDARD standard])必选项:PROJECT_NAME项目名称字母、数字、下划线建议使用 PascalCase可选参数:VERSION项目版本号如 1.0.0会自动定义 PROJECT_VERSION_* 变量。LANGUAGES支持的编程语言如 C、CXX、Fortran、ASM 等默认 C 和 CXX。DESCRIPTION项目描述用于生成文档或打包。HOMEPAGE_URL项目主页 URL。CXX_STANDARDC 标准如 17、20需 CMake 3.12。这个参数目前不要通过这个project来设置2.2 set2.2.1 QT_QML_GENERATE_QMLLS_INI含义这是 Qt 特有的配置。它告诉 Qt 的构建系统在生成项目时顺便生成一个名为qmlls.ini的配置文件。为什么要加它解决“代码瞎了”的问题在 Qt Quick (QML) 开发中Qt Creator 有时候分不清 C 注册的类和 QML 定义的类导致代码补全失效、跳转失效。开启后qmlls(QML Language Server) 会读取这个配置文件更精准地扫描你的项目结构从而在编辑器里提供更聪明的代码补全、语法高亮和跳转功能。2.2.2 CMAKE_CXX_STANDARD_REQUIRED通常配合CMAKE_CXX_STANDARD 一个是声明C的标准QT_QML_GENERATE_QMLLS_INI:防止“静默降级”如果不加这一行当你的编译器太老比如老旧的 GCC 4.8不支持 C17 时CMake 可能会“自作聪明”地回退到 C11set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)set(QT_QML_GENERATE_QMLLS_INI ON)2.3 find_packagefind_package(Qt6 [版本号] [REQUIRED] [COMPONENTS 组件1 组件2 ...])REQUIRED找不到 Qt 或指定组件时终止配置并报错。COMPONENTS指定需要的 Qt 模块如Core、Widgets、Gui。其实这个就是去找qt6的Qt6Config.cmake文件去完成自动链接。find_package(Qt6 6.8.3 REQUIRED COMPONENTS Quick)2.4 qt_standard_project_setup这是一个“硬性门槛”。它的意思是“我的项目必须用 Qt 6.8 或更高版本。如果你电脑里装的是 Qt 6.5 或 6.6请直接报错停止不要勉强编译。”为什么要加它qt_standard_project_setup(REQUIRES 6.8)一键省心模式: 自动帮你写好几十行样板代码顺便强制检查你的 Qt 版本是否达标。在 Qt 6.8 之前你需要写一堆命令来配置项目比如set(CMAKE_AUTOMOC ON)自动处理元对象编译器。set(CMAKE_AUTORCC ON)自动处理资源编译器。set(CMAKE_AUTOUIC ON)自动处理界面文件。还要手动设置 C 标准、编译器警告等级等等。qt_standard_project_setup()这一行代码就把上面所有这些杂事全干了。它根据 Qt 官方推荐的最佳实践自动帮你配置好了一切。2.5 qt_add_executable生成一个叫appSonicMusic的程序源代码是main.cpp2.6qt_add_qml_moduleqt_add_qml_module(appSonicMusicURI SonicMusic #把 Main.qml 打包成一个叫 SonicMusic 的模块。” 使用时直接 import即可,更改了文件路径后只需要在这里修改,不需要再引入的地方每个都挨个去修改文件路径QML_FILESMain.qml)作用:第一个参数appSonicMusic告诉 CMake“我要把下面的 QML 配置挂载到刚才那个 exe 程序上”。定义命名空间URI SonicMusic是最关键的一句。它定义了一个模块名。这意味着在你的 C 代码或 QML 代码里这个模块下的类型都属于SonicMusic这个“家族”。指定文件QML_FILES Main.qml告诉 CMake“把Main.qml编译进这个模块”。结果CMake 会做一件很酷的事它会扫描Main.qml。它会把Main.qml编译成一个独立的动态库比如SonicMusic.dll或.so。它会自动把这个库链接到你的appSonicMusic.exe上。2.7 set_target_properties 配置应用属性这部分代码是给生成的程序“贴标签”告诉操作系统这个程序长什么样、是什么版本。WIN32_EXECUTABLE TRUE作用这是给Windows用的。含义告诉 CMake“我要生成一个标准的 Windows 窗口程序.exe而不是一个黑框框的控制台程序”。效果编译出来的程序双击直接运行不会弹出一个难看的黑色命令行窗口。MACOSX_BUNDLE TRUE作用这是给macOS用的。含义告诉 CMake“在 Mac 上程序不是一个单独的文件而是一个‘应用包’.app 文件夹”。效果生成的不是appSonicMusic而是appSonicMusic.app。MACOSX_BUNDLE_BUNDLE_VERSION和SHORT_VERSION_STRING作用设置版本号。含义BUNDLE_VERSION通常是内部构建号比如 1.0.0.23。SHORT_VERSION_STRING是给用户看的版本号比如 1.0。效果你在 macOS 的“访达”里右键点击程序 - “显示简介”或者在 Windows 的 exe 属性里看到的版本号就是这里设置的。MACOSX_BUNDLE_GUI_IDENTIFIER(被注释掉的那行)含义这是 macOS 或 iOS 应用的“身份证号”比如com.sonymusic.app。建议如果你打算把你的 App 发布到 Mac App Store 或者要在 iPad 上运行一定要把这一行取消注释并改成你独一无二的域名倒写。否则签名会出问题。2.8 target_link_libraries链接核心库作用这是最基础的“接线”工作。含义告诉链接器“我的程序用到了 Qt 的 Quick 模块Qt6::Quick请把它的代码链接进来”。注意虽然你用了qt_add_qml_module但那个命令主要处理 QML 资源。如果你的main.cpp里用了QGuiApplication或者QQmlEngine这些 C 类你依然需要显式链接Qt6::Quick它通常会自动包含Qt6::Gui和Qt6::Qml。PRIVATE表示这个依赖只在这个程序内部使用不需要暴露给外部。2.9 install定义安装规则install(TARGETS appSonicMusicBUNDLE DESTINATION .LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})作用这是告诉 CMake“当我运行cmake --install .命令时请把生成的文件复制到哪里去”。详细解释BUNDLE DESTINATION .针对macOS/iOS。意思是把生成的.app包直接放到安装目录的根目录下。RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}针对Windows/Linux。意思是把生成的.exe或可执行二进制文件放到bin目录下通常${CMAKE_INSTALL_BINDIR}就是bin。LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}针对Linux/macOS。意思是如果生成了动态库.so或.dylib把它们放到lib目录下。三 c关联引擎创建QQmlApplicationEngine engine;创建engine对象。此时QML 引擎已经启动但还没有加载任何界面它是空的。错误处理安全网QObject::connect( engine, QQmlApplicationEngine::objectCreationFailed, app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection);这段代码非常关键它是程序的“崩溃保护机制”信号objectCreationFailed。如果 QML 代码有语法错误比如少写了花括号或者根对象创建失败引擎就会发出这个信号。槽[]() { QCoreApplication::exit(-1); }。这是一个 Lambda 表达式匿名函数。一旦收到失败信号它立刻执行退出命令并返回错误码-1。连接方式Qt::QueuedConnection。这确保了退出操作是在主线程的事件循环中执行的防止多线程竞争导致的崩溃。作用如果没有这段代码即使 QML 加载失败了程序可能还会挂起在后台或者白屏卡死。有了它程序会优雅地报错并退出。核心启动loadFromModule这是最核心的改动SonicMusic这是你在CMakeLists.txt中定义的URI。Main这是你要加载的 QML 组件名称对应Main.qml。原理旧写法engine.load(QUrl(qrc:/Main.qml))。这种方式强依赖文件路径如果文件移动了或者打包方式变了这里就得改。新写法loadFromModule。它告诉引擎“去已注册的模块列表里找叫SonicMusic的那个模块然后加载它的Main组件。”优势C 代码完全解耦了文件路径。不管Main.qml是在src目录还是ui目录只要 CMake 里的 URI 没变这行 C 代码永远不需要修改。#include QGuiApplication #include QQmlApplicationEngine int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; QObject::connect( engine, QQmlApplicationEngine::objectCreationFailed, app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.loadFromModule(SonicMusic, Main); return QCoreApplication::exec(); }

更多文章