输入关键词开始搜索

CMake + QML 环境配置

101. Qt 项目 CMake 集成 QML 环境配置

日期: 2026-05-20 关联开发任务: 阶段 1 任务 1.1 项目初始化 关联设计文档: 001.概要设计文档、009.开发规范文档


一、问题/需求描述

Qt Creator 6.x 新建项目默认生成 QWidget + QMainWindow + .ui 表单 模板。但概要设计文档 [001:行15] 明确要求 UI 层使用 QML(Qt Quick)。需要在不引入 qmake 的前提下,用纯 CMake 将项目切换到 QML 技术栈,并保留跨平台编译能力(Windows/macOS/Linux)。

附带问题:项目启动时误以为 QML 需要 qmake 构建系统——这是 Qt 历史资料最常见的误导。


二、思路

  1. 澄清误解:QML 是 Qt 的运行时模块(Qt6::Quick),通过 find_package + target_link_libraries 引入,与 Qt6::Widgets 平级,不需要也不应该用 qmake
  2. CMake 改造:在现有 CMakeLists.txt 的 find_package 中增加 QuickQuickControls2 组件;target_link_libraries 增加对应库
  3. 入口改造main.cppQApplication + QMainWindow::show() 改为 QQmlApplicationEngine 加载 QML 文件
  4. 资源管理:创建 .qrc 文件索引 QML 文件和静态资源,通过 qrc:/ 前缀引用
  5. 清理遗留:删除 mainwindow.hmainwindow.cppmainwindow.ui——它们是纯 QWidget 代码,与 QML 方向互斥

三、逻辑推导

QML 加载链

main.cpp
  ↓ QApplication app(argc, argv)
  ↓ QQmlApplicationEngine engine
  ↓ engine.load("qrc:/qml/main.qml")
  ↓ 解析 .qrc → 定位 src/ui/qml/main.qml
  ↓ Qt Quick 运行时渲染 ApplicationWindow

CMake 模块依赖链

SmartDietManager
  ├── Qt6::Widgets      ← 保留(未来系统托盘/文件对话框)
  ├── Qt6::Quick        ← QML 运行时引擎
  ├── Qt6::QuickControls2 ← ApplicationWindow / Button 等控件
  ├── Qt6::Sql          ← 预置(1.3 数据库用)
  ├── Qt6::Network      ← 预置(HTTP REST 用)
  └── Qt6::WebSockets   ← 预置(阶段 8 实时同步用)

四、实施方案

4.1 CMakeLists.txt 核心改动

# 新增 Quick QuickControls2 Sql Network WebSockets 模块
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS
    Widgets Quick QuickControls2 Sql Network WebSockets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS
    Widgets Quick QuickControls2 Sql Network WebSockets LinguistTools)

# 移除 Widget 源文件,加入 QML 资源文件
set(PROJECT_SOURCES
    src/app/main.cpp
    resources/translations/SmartDietManager_zh_CN.ts
    resources.qrc                          # ← 新增
)

# 链接所有模块
target_link_libraries(SmartDietManager PRIVATE
    Qt${QT_VERSION_MAJOR}::Widgets
    Qt${QT_VERSION_MAJOR}::Quick
    Qt${QT_VERSION_MAJOR}::QuickControls2
    Qt${QT_VERSION_MAJOR}::Sql
    Qt${QT_VERSION_MAJOR}::Network
    Qt${QT_VERSION_MAJOR}::WebSockets
)

4.2 resources.qrc(新建)

<RCC>
    <qresource prefix="/qml">
        <file alias="main.qml">src/ui/qml/main.qml</file>
    </qresource>
</RCC>

4.3 main.cpp(重写)

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "SmartDietManager_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            app.installTranslator(&translator);
            break;
        }
    }

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
    if (engine.rootObjects().isEmpty()) return -1;
    return app.exec();
}

4.4 main.qml(新建)

import QtQuick
import QtQuick.Controls
import QtQuick.Window

ApplicationWindow {
    id: root
    width: 800
    height: 600
    visible: true
    title: "SmartDietManager"
    color: "#F5F5F5"

    Text {
        anchors.centerIn: parent
        text: "🥗 SmartDietManager"
        font.pixelSize: 24
        color: "#333333"
    }
}

4.5 删除文件

src/ui/views/mainwindow.h      ← QMainWindow 声明
src/ui/views/mainwindow.cpp    ← QMainWindow 实现
src/ui/views/mainwindow.ui     ← Qt Designer 表单

五、可行性分析

维度评估
Qt 兼容性QQmlApplicationEngine 自 Qt 5.1 起可用,Qt 6.x 完全支持
CMake 兼容性CMAKE_AUTORCC ON 自动处理 .qrc 编译,无需手写命令
跨平台QML 在 Windows/macOS/Linux 均原生渲染,无需平台适配代码
与现有代码冲突删除的 Widget 文件无其他引用,安全移除
Qt::Widgets 保留为后续 QSystemTrayIconQFileDialog 预留接口

六、验证

验证项方法结果
CMake 配置无报错cmake -S . -B build -DCMAKE_PREFIX_PATH=...
MOC/QRC/RCC 自动处理检查 build 目录生成文件
编译零错误零警告cmake --build build
QML 窗口可启动Qt Creator 运行验证(用户确认)
无 qmake 依赖项目中不存在 .pro / .pri 文件