C++ cmake工程引入qt6和Quick 教程

前言

在现代软件开发中,跨平台的图形用户界面(GUI)和可视化功能已经变得非常重要。Qt和Qt Quick(基于QML)是强大而灵活的工具,可以帮助开发者快速构建出色的应用程序。然而,当你已经有一个基于C++和CMake的工程时,将Qt和Qt Quick引入可能需要一些指导。

本教程将帮助具有C++和CMake基础知识的开发者将Qt和Qt Quick引入现有的CMake工程。我们将介绍如何设置CMakeLists.txt文件以便使用Qt模块,以及如何在C++和QML代码中实现跨语言的交互。通过本教程,你将能够将Qt和Qt Quick应用到你的项目中,创建出富有吸引力的用户界面和可视化效果。

QML简介

QML是Qt的一种声明式编程语言,用于设计和实现跨平台的用户界面。与Qt Widgets相比,QML具有以下优势:

  1. 简洁的语法:QML具有简洁、易读的语法,使得创建和修改用户界面变得非常直观。它允许你以更少的代码实现相同的功能,从而提高开发效率。
  2. 强大的动画和特效支持:QML内置了丰富的动画和特效支持,使得创建具有吸引力的用户界面变得更加容易。你可以方便地为界面元素添加动画效果,提高用户体验。
  3. 跨平台兼容性:QML可以很好地支持不同平台和设备,使得跨平台应用开发变得更加容易。使用QML,你可以为桌面、移动和嵌入式设备创建统一的用户界面。
  4. 面向对象的编程:QML支持面向对象编程,允许你创建可重用的组件和模块。这有助于提高代码的模块化和可维护性。
  5. 与C++的紧密集成:QML可以轻松地与C++代码进行集成,允许你在QML界面中使用C++实现的功能。这使得QML非常适合与现有的C++项目一起使用。

尽管QML具有这些优势,但它并不总是比Qt Widgets更容易实现。实际上,两者之间的难易程度取决于你的需求和经验。Qt Widgets在某些场景下可能更适用,尤其是对于传统的桌面应用程序,以及对性能要求较高的场景。

总的来说,QML在许多方面具有优势,但你应该根据项目需求和个人喜好来选择最适合的技术。如果你对QML感兴趣,我建议你尝试使用它来实现一些简单的项目,以便更好地了解它的特点和优势。

锻炼C++水平

  1. 使用Qt Widgets:虽然QML是一种强大的界面设计语言,但使用Qt Widgets同样可以创建出优秀的界面,同时更多地使用C++代码。通过使用Qt Widgets,你可以在实际项目中应用和提高C++编程技能。
  2. 将C++和QML结合:QML和C++可以很好地集成在一起。你可以使用C++编写应用程序的核心逻辑和算法,然后将这些功能暴露给QML以在用户界面中使用。这样,你既能锻炼C++编程能力,又能学习QML的使用方法。
  3. 参与开源项目:加入一个使用C++的开源项目,可以让你在实际项目中应用和提高C++编程技能。参与开源项目可以帮助你了解更多关于C++的最佳实践和技巧,同时还能扩展你的技术网络。
  4. 阅读C++相关书籍和教程:阅读高质量的C++书籍和教程可以帮助你深入了解C++语言的特性和最佳实践。一些经典的C++书籍,如《Effective C++》、《C++ Primer》和《The C++ Programming Language》,都是值得一读的好书。
  5. 解决编程挑战和问题:在网上寻找C++编程挑战和问题,例如LeetCode、HackerRank等平台上的编程题目。这些挑战可以帮助你锻炼编程能力,提高解决问题的速度和效率。
  6. 学习C++新特性:C++语言一直在不断发展,新的标准和特性会定期推出。关注并学习这些新特性,可以让你保持C++知识的更新,同时提高编程能力。

通过采取这些策略,你可以在实际项目中锻炼和提高C++编程技能。同时,学习QML可以帮助你更好地应对不同类型的项目需求,让你在软件开发领域具有更强的竞争力。祝你在C++和QML的学习过程中取得好成绩!

cmake修改方法

方式一(qt6_add_resources)

要将现有的C++ CMake工程引入Qt6环境并使用Qt和QML,你需要执行以下步骤:

  1. 安装Qt6:如果你还没有安装Qt6,请从官方网站下载并安装。确保你安装了Qt6的CMake模块。
  2. 修改CMakeLists.txt:在你的C++ CMake工程中,打开CMakeLists.txt文件。首先,确保找到Qt6包,然后链接到需要的Qt6模块。例如,如果你需要使用Qt6 Core、Gui和Quick模块,可以添加以下内容:
    find_package(Qt6 COMPONENTS Core Gui Quick REQUIRED)
    
    然后,将这些模块链接到你的目标(例如,你的可执行文件):
    target_link_libraries(your_target_name PRIVATE Qt6::Core Qt6::Gui Qt6::Quick)
    
  3. 添加QML文件:在工程目录下创建一个QML文件夹,将所有QML文件放在该文件夹中。然后,在CMakeLists.txt中使用file(GLOB ...)命令将这些文件添加到工程中。例如:
    file(GLOB QML_FILES qml/*.qml)
    
    将QML文件添加到可执行文件的资源文件中:
    qt6_add_resources(your_target_name "qml"
        PREFIX
            "/"
        FILES
            ${QML_FILES}
    )
    
  4. 创建主入口:在你的C++工程中创建一个main.cpp文件(如果尚未创建),并添加以下代码以设置Qt和QML环境:
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
          
          
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
          
          
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
  5. 注册C++类:在main.cpp中,使用qmlRegisterType函数注册你的C++类,使其可以在QML中使用。例如:
    qmlRegisterType<YourCppClass>("com.example.yourclassname", 1, 0, "YourCppClass");
    
    然后在QML文件中,可以通过以下方式导入和使用你的C++类:
    import com.example.yourclassname 1.0
    
    YourCppClass {
        // ...
    }
    
  6. 编译和运行:现在你的C++ CMake工程已经集成了Qt6和QML,你可以编译和运行它。如果一切正常,你应该可以看到你的QML界面。

方式二 (qt_add_qml_module )

当然,你也可以使用qt_add_qml_module函数在CMake项目中添加QML模块。这是一个简化了QML资源添加的便捷方法。下面是如何使用qt_add_qml_module的步骤:

  1. 安装Qt6:如果你还没有安装Qt6,请从官方网站下载并安装。确保你安装了Qt6的CMake模块。
  2. 修改CMakeLists.txt:在你的C++ CMake工程中,打开CMakeLists.txt文件。首先,确保找到Qt6包,然后链接到需要的Qt6模块。例如,如果你需要使用Qt6 Core、Gui和Quick模块,可以添加以下内容:
    find_package(Qt6 COMPONENTS Core Gui Quick REQUIRED)
    
    然后,将这些模块链接到你的目标(例如,你的可执行文件):
    target_link_libraries(your_target_name PRIVATE Qt6::Core Qt6::Gui Qt6::Quick)
    
  3. 添加QML文件:在工程目录下创建一个QML文件夹,将所有QML文件放在该文件夹中。
  4. 使用qt_add_qml_module:在CMakeLists.txt中,使用qt_add_qml_module函数将QML文件添加到工程中。例如:
    qt_add_qml_module(your_target_name
        URI com.example.yourclassname
        VERSION 1.0
        QML_FILES
            qml/main.qml
    )
    
    其中your_target_name是你的可执行文件的目标名称,URI指定了模块的标识符,VERSION设置了模块的版本,QML_FILES列出了所有的QML文件。
  5. 创建主入口:在你的C++工程中创建一个main.cpp文件(如果尚未创建),并添加以下代码以设置Qt和QML环境:
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
          
          
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/qml/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
          
          
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
  6. 注册C++类:在main.cpp中,使用qmlRegisterType函数注册你的C++类,使其可以在QML中使用。例如:
    qmlRegisterType<YourCppClass>("com.example.yourclassname", 1, 0, "YourCppClass");
    
    然后在QML文件中,可以通过以下方式导入和使用你的C++类:
    import com.example.yourclassname 1.0
    
    YourCppClass {
        // ...
    

其他相关知识

为什么会有<target_name>_other_files

这个问题是因为 qt_add_qml_module 函数在将 QML 文件添加到项目时,会创建一个名为 <target_name>_other_files 的辅助目标。这个辅助目标是用于在 Qt Creator 中显示 QML 文件和其他相关文件。这个目标对于构建过程没有影响,也不会生成任何二进制文件。它只是为了在 Qt Creator 中提供更好的文件组织和显示。

qt_standard_project_setup() 函数

qt_standard_project_setup() 函数。这个函数会在内部配置 CMake 以便为 Qt 项目生成一个更简洁的目录结构,这意味着它会自动处理 QML 模块和资源的添加,而不会生成额外的辅助目标。

qt_standard_project_setup() 函数在调用 qt_add_qml_module() 之前已经为项目配置了资源管理,所以你没有看到任何 <target_name>_other_files 目标。

如果你想在自己的项目中使用类似的设置,可以尝试在调用 find_package()add_executable() 之后添加 qt_standard_project_setup() 函数。这样,你可以得到一个更简洁的目录结构,同时保留 Qt Creator 的 QML 模块管理功能。

请注意,qt_standard_project_setup() 函数是 Qt 的一个实验性功能,未来版本的 Qt 可能会对其进行更改或移除。在使用这个函数时,请确保你了解其实现细节,并准备好在将来的 Qt 版本中进行必要的调整。

qt_add_qml_module()qt6_add_resources()的方式差异

qt_add_qml_module()qt6_add_resources() 都可以将 QML 文件和其他资源添加到项目中,但它们的功能和目标有所不同:

  1. qt_add_qml_module()
    • 是为了简化 QML 模块的创建和管理而设计的。
    • 自动生成 QRC 文件。
    • 可以指定模块的 URI 和版本,这对于在项目中使用 QML 模块很有用。
    • 会创建一个名为 <target_name>_other_files 的辅助目标,用于在 Qt Creator 中显示 QML 文件和其他相关文件,以便于查看和管理。
    • 更适合用于包含 QML 模块的项目,可以自动处理 QML 模块的注册和资源管理。
  2. qt6_add_resources()
    • 是一个更通用的函数,用于将资源(如图像、文本文件等)添加到项目中。
    • 需要手动创建 QRC 文件。
    • 不会创建 <target_name>_other_files 辅助目标,因此在 Qt Creator 中不会有额外的文件显示。
    • 适用于不需要 QML 模块特性的项目,或者需要更细粒度控制资源管理的项目。

总的来说,如果你的项目需要使用 QML 模块并希望简化模块的创建和管理,建议使用 qt_add_qml_module()。如果你的项目只需要将 QML 文件和其他资源添加到项目中,而不需要使用 QML 模块特性,或者希望有更多的控制权,那么 qt6_add_resources() 是一个更好的选择。

const QUrl url(u"qrc:///Main.qml"_qs);和const QUrl url(QStringLiteral(“qrc:///Main.qml”));的区别

两者之间的主要区别在于字符串字面值的表示方法和编码:

  1. const QUrl url(u"qrc:///Main.qml"_qs);

    这里,u 前缀表示该字符串字面值为一个 UTF-16 编码的 Unicode 字符串。字符串后面的 _qs 用户自定义字面量(User-defined Literal,UDL),它是 Qt 提供的用于将字符串字面值转换为 QString 类型的便捷方法。在这种情况下,字符串字面值是一个 UTF-16 编码的 Unicode 字符串,最终转换为 QString 类型。

  2. const QUrl url(QStringLiteral("qrc:///Main.qml"));

    在这里,QStringLiteral 是一个 Qt 宏,用于在编译时将字符串字面值转换为一个 QString 类型的对象。该宏的优势在于避免了在运行时创建 QString 对象,从而提高了性能。在这种情况下,字符串字面值是一个普通的字符串,QStringLiteral 将其转换为 QString 类型。

在实际使用中,这两种方法都可以实现相同的功能,即创建一个 QUrl 对象来表示资源文件的 URL。只是它们在编译时处理字符串字面值的方式略有不同。考虑到性能和简洁性,推荐使用 QStringLiteral 方法。

qt种qrc查找原理

当您使用 qrc: 前缀引用资源文件时,Qt 会自动查找所有已注册的资源文件。在构建过程中,qt_add_resources()qt6_add_resources() 函数会将资源文件(如 resources.qrc)编译成二进制文件,并将它们嵌入到最终的可执行文件中。当您在运行时使用 qrc: 前缀引用资源文件时,Qt 会在所有已注册的资源文件中查找匹配的条目。

因此,您不需要在引用资源文件时指定 resources.qrc,因为 Qt 会自动在所有已注册的资源文件中查找正确的文件。如果您有多个 .qrc 文件,只要确保它们都通过 qt_add_resources()qt6_add_resources() 函数正确注册,Qt 就会在所有已注册的资源文件中查找。

需要注意的是,在使用多个 .qrc 文件时,请确保文件名和路径不会发生冲突,以避免混淆和潜在的错误。

使用无前缀的 URL 引用资源文件

根据 Qt 官方文档,从 Qt 6.2 开始,可以在 QML 代码中省略前缀,但在 C++ 代码中,仍然需要使用 qrc: 前缀来引用资源文件。这是因为 QML 和 C++ 是两种不同的语言,它们有不同的命名规则和语法结构。

在 QML 中,可以使用 import 语句来引用 QML 文件,而不需要使用前缀。但是,在 C++ 中,必须使用 qrc: 前缀来引用资源文件,以便在 QML 中使用。

因此,如果您想在 QML 中使用 C++ 代码,必须在 QML 代码中使用 qrc: 前缀来引用资源文件。如果您只想在 QML 中使用 C++ 代码,则可以省略前缀。

猜你喜欢

转载自blog.csdn.net/qq_21438461/article/details/130464065