【Qt QML】用CMake管理Qt工程

news2024/12/26 22:14:42

CMake是一个开源、跨平台的工具系列,用于构建、测试和打包软件。CMake使用简单的独立配置文件来控制软件编译过程。与许多跨平台系统不同,CMake被设计为与本地构建环境结合使用。
下面我们在CMake项目中使用Qt的最基本方法。首先,创建一个基本的控制台应用程序。然后,将该项目扩展为使用Qt Widgets的GUI应用程序。

一、用CMake构建控制台应用程序,构建系统选择CMake(Qt6支持)

在这里插入图片描述
Qt Creator为我们自动生成了一个CMakeList.txt,如图:

在这里插入图片描述
CMakeList.txt是CMake项目的核心配置文件,位于项目根目录下,用于定义项目的构建规则和配置选项。通过编写CMake语法,可以在CMakeList.txt中定义项目名称、需要的源文件、依赖项、编译标志、安装规则等。这样可以实现跨平台的项目构建和管理,提供了灵活性和可扩展性。工程中自动生成的CMakeList内容如下:

cmake_minimum_required(VERSION 3.14)         #指定构建应用程序最低的CMake版本,通常放在CMakeList最开始

project(TestCMakeConsole LANGUAGES CXX)      #设定项目名称和默认版本,Languages参数用来告诉CMake程序是用C++写的

#用来告诉CMake工具自动处理UI文件、MOC文件和资源文件的指令
set(CMAKE_AUTOUIC ON)                       #开启自动生成UI头文件的功能,即对应UI文件(.ui)会生成对应的UI头文件,无需手动编写
set(CMAKE_AUTOMOC ON)                       #开启自动生成MOC文件的功能,即处理带有Q_OBJECT宏的QObject派生类的头文件,生成相应的MOC文件。MOC (Meta-Object Compiler) 是用于处理信号槽机制的工具
set(CMAKE_AUTORCC ON)                       #开启自动生成资源文件的功能,即处理.qrc文件,生成相应的资源文件

set(CMAKE_CXX_STANDARD 17)                  #指定需要C++17或者高的编译器支持
set(CMAKE_CXX_STANDARD_REQUIRED ON)         #强制指定编译器支持,如果编译器太旧,CMake将打印错误

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)            #查找Qt5或Qt6并导入Core模块,Required参数标志是告诉CMake这种查找是强制的,如果没找到则中止
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core)       #强制指定到的Qt版本是由QT_VERSION_MAJOR参数指定的版本,找到后导入Core模块

add_executable(TestCMakeConsole             #告诉CMake我们想要构建一个名为TestCMakeConsole的可执行文件作为目标。目标应该从c++源文件main.cpp构建。注意,这里通常不列出头文件。
  main.cpp
)
target_link_libraries(TestCMakeConsole Qt${QT_VERSION_MAJOR}::Core)   #告诉CMake, TestCMakeConsole可执行文件通过引用上面find_package()调用导入的Qt6::Core目标来使用Qt Core。

include(GNUInstallDirs)                     #包含GNUInstallDirs模块,它定义了一些安装目录变量,方便在后续的安装过程中使用

#指定了一个名为TestCMakeConsole的目标,指定了在安装时将该目标生成的库文件安装到${CMAKE_INSTALL_LIBDIR}目录下,将生成的可执行文件安装到${CMAKE_INSTALL_BINDIR}目录下。
#这样可以确保在安装项目时,生成的文件会被安装到正确的目录下。
install(TARGETS TestCMakeConsole
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

二、用CMake构建GUI应用程序

在这里插入图片描述
同样,我们继续分析Qt Creator为Demo工程自动生成的CMakeList.txt。

cmake_minimum_required(VERSION 3.5)     #指定构建应用程序最低的CMake版本为3.5,通常放在CMakeList最开始

project(testCMakeGui VERSION 0.1 LANGUAGES CXX)   #设定项目名称和默认版本,Languages参数用来告诉CMake程序是用C++写的

set(CMAKE_AUTOUIC ON)                   #见上文
set(CMAKE_AUTOMOC ON)                   #见上文
set(CMAKE_AUTORCC ON)                   #见上文

set(CMAKE_CXX_STANDARD 17)              #见上文
set(CMAKE_CXX_STANDARD_REQUIRED ON)     #见上文

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)             #见上文,不同的是基于QWidget的GUI应用我们需要导入Widgets模块
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)        #见上文

set(PROJECT_SOURCES                     #通过设置PROJECT_SOURCES变量来指定项目所需的所有源文件。这些源文件将在项目构建时被编译并链接到可执行文件中。
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

#首先检查 Qt 版本是否大于或等于 6。如果是,则使用 qt_add_executable() 函数来创建一个名为 testCMakeGui 的可执行文件,指定 MANUAL_FINALIZATION,并包含之前定义的项目源文件列表。
#如果 Qt 版本是 6,还会有一个注释部分,说明如何在 Android 下为 testCMakeGui 定义属性。该注释提供了一个 set_property() 调用的示例,用于指定 QT_ANDROID_PACKAGE_SOURCE_DIR。
#如果 Qt 版本小于6,代码将进入 else 分支。在此分支中,会检查是否为 Android 平台。如果是 Android 平台,将使用 add_library() 函数创建一个名为 testCMakeGui 的共享库(SHARED),并包含项目源文件列表。
#同样也有一个注释,用于定义 Qt 5 中 Android 平台的属性设置。
#如果不是 Android 平台,将使用 add_executable() 函数创建一个名为 testCMakeGui 的可执行文件,并包含项目源文件列表。
#这段代码根据 Qt 版本和平台类型选择不同的构建方式,并为每种情况定义了相应的属性。这样可以确保项目在不同的环境和版本下都能正确构建。
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(testCMakeGui
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
         )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET testCMakeGui APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(testCMakeGui SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(testCMakeGui
            ${PROJECT_SOURCES}
        )
    endif()
endif()

#确保了 testCMakeGui 目标可以访问并使用 Qt Widgets 模块中的功能,这样在构建和运行项目时就能正确地链接和使用 Qt 组件
target_link_libraries(testCMakeGui PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
#在 Qt 6.1 及以后的版本中,Qt for iOS会自动设置MACOSX_BUNDLE_GUI_IDENTIFIER,但如果Qt版本低于6.1.0,则需要手动设置一个固定的Bundle Identifier,以确保应用程序在macOS上正确识别和管理。
#默认的Bundle Identifier设置为com.example.testCMakeGui,可以根据需要修改。
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.testCMakeGui)
endif()

#通过set_target_properties函数设置了testCMakeGui目标的属性。其中,${BUNDLE_ID_OPTION}是之前定义的用于设置Bundle Identifier的变量。
#另外,MACOSX_BUNDLE_BUNDLE_VERSION被设置为项目版本,MACOSX_BUNDLE_SHORT_VERSION_STRING被设置为项目主版本号和次版本号的组合。MACOSX_BUNDLE属性被设置为TRUE,表示当前目标是一个macOS bundle。
#WIN32_EXECUTABLE属性被设置为TRUE,表示当前目标是一个Win32可执行程序。
set_target_properties(testCMakeGui PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

#见上文
include(GNUInstallDirs)
install(TARGETS testCMakeGui
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

#如果主版本号等于6,则调用qt_finalize_executable函数来完成testCMakeGui可执行文件的最终配置。
if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(testCMakeGui)
endif()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1638674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

向量体系结构:向量执行时间

看《计算机体系结构 量化研究方法》做的笔记,接着上一篇写 计算机体系结构:向量体系结构介绍-CSDN博客 向量处理器工作的示例 SAXPY或DAXPY循环。 aXY SAXPY代表“单精度aX加Y”,进行单精度浮点数的运算,其中a是一个标量&#x…

测试开发工具开发 -JMeter 函数二次开发

在JMeter中开发自定义函数是一个常见的需求,允许我们扩展JMeter的功能以适应特定的测试需求。自定义函数可以用来处理数据,生成输出,或者执行特定的运算。通过JMeter函数二次开发可以帮我们解决实际测试过程中造数难的问题 用过JMeter的同学…

搭建vue3组件库(三): CSS架构之BEM

文章目录 1. 通过 JS 生成 BEM 规范名称1.1 初始化 hooks 目录1.2 创建 BEM 命名空间函数1.3 通过 SCSS 生成 BEM 规范样式 2. 测试 BEM 规范 BEM 是由 Yandex 团队提出的一种 CSS 命名方法论,即 Block(块)、Element(元素&#xf…

WORD排版常见问题与解决方案

前言 近期使用word软件进行论文排版工作,遇到了一些常见的问题,记录一下,避免遗忘。 基本配置 系统环境:win10/win11 word版本:Microsoft Office LTSC 专业增强版 2021 问题与解决方案 问题1:页眉显示内…

C——双向链表

一.链表的概念及结构 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。什么意思呢?意思就是链表在物理结构上不一定是连续的,但在逻辑结构上一定是连续的。链表是由一个一个的节点连…

使用递归函数,将一串数字每位数相加求和

代码结果&#xff1a; #include<stdio.h> int DigitSum(unsigned int n) {if (n > 9)return DigitSum(n / 10) (n % 10);elsereturn n; } int main() {unsigned int n;scanf("%u", &n);int sum DigitSum(n);printf("%d\n", sum);return 0; …

持续更新|UNIAPP适配APP遇到的问题以及解决方案

在使用UNIAPP开发APP的时候遇到的一些奇奇怪怪问题记录 组件样式丢失 问题&#xff1a;组件引入界面中&#xff0c;在小程序和H5环境下样式正常&#xff0c;而在APP中却出现高度异常问题 解决&#xff1a;增加view标签将组件包裹起来即可正常显示 解决前&#xff1a; 解决后…

SCI一区 | MFO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测(Matlab)

SCI一区 | MFO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测&#xff08;Matlab&#xff09; 目录 SCI一区 | MFO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测&#xff08;Matlab&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现MFO-CNN…

JAVA第二周学习笔记

文章目录 JAVA第二周学习笔记IDEA方法格式带参数及返回值的方法方法的重载方法的内存 二维数组静态初始化动态初始化 面向对象类和对象如何定义类如何得到对象注意 封装封装的优点private关键字成员变量和局部变量 this关键字构造方法作用类型特点执行时机定义重载 标准javabea…

Linux进程——进程的创建(fork的原理)

前言&#xff1a;在上一篇文章中&#xff0c;我们已经会使用getpid/getppid函数来查看pid和ppid,本篇文章会介绍第二种查看进程的方法&#xff0c;以及如何创建子进程&#xff01; 本篇主要内容&#xff1a; 查看进程的第二种方法创建子进程系统调用函数fork 在开始前&#xff…

什么是哈希表(HashTable)?

目录 一、概念 二、哈希冲突 减少哈希冲突的办法&#xff1a; 1、设计合理的哈希函数 哈希函数设计原则&#xff1a; 常用的哈希函数&#xff1a; 2、降低负载因子&#xff08;必须重点掌握&#xff09; 哈希冲突的解决 第一类&#xff1a;闭散列 第二类&…

实时监控RTSP视频流并通过YOLOv5-seg进行智能分析处理

在完成RTSP推流之后&#xff0c;尝试通过开发板接收的视频流数据进行目标检测&#xff0c;编写了一个shell脚本实现该功能&#xff0c;关于视频推流和rknn模型的部署请看之前的内容或者参考官方的文档。 #!/bin/bash # 设置脚本使用的shell解释器为bashSEGMENT_DIR"./seg…

【模板】前缀和

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和模板题。 前缀和中数组下标为1~n。 前缀和&#xff1a;pre[i]pre[i-1]a[i]; 某段区间 [l,r]的和&#xff1a;pre[r]-pre[l-1] 3.…

【数学建模】2024五一数学建模C题完整论文代码更新

最新更新&#xff1a;2024五一数学建模C题 煤矿深部开采冲击地压危险预测&#xff1a;建立基于多域特征融合与时间序列分解的信号检测与区间识别模型完整论文已更新 2024五一数学建模题完整代码和成品论文获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/gyoz9ou5upv…

unity制作app(2)--主界面

1.先跳转过来&#xff0c;做一个空壳&#xff01;新增场景main为4号场景&#xff01; 2.登录成功跳转到四号场景&#xff01; 2.在main场景中新建canvas&#xff0c;不同的状态计划用不同的panel来设计&#xff01; 增加canvas和底图image 3.突然输不出来中文了&#xff0c;浪…

【19-文本数据处理:Scikit-learn中的自然语言处理技术】

文章目录 前言理解文本数据文本预处理文本清洗分词停用词去除向量化文本数据词袋模型TF-IDF变换构建文本分类模型模型评估与调优结论前言 欢迎回到我们的Scikit-learn系列,在这篇文章中,我们将探讨如何使用Scikit-learn来处理文本数据,这是自然语言处理(NLP)的基础。你将学…

为家庭公网IP配置DDNS域名

文章目录 域名配置域名更新frp配置修改 在成功完成frp改造Windows笔记本实现家庭版免费内网穿透之后&#xff0c;某天我突然发现内网穿透失效了&#xff0c;一番排查之后原来是路由器对应的公网IP更换了。果然我分到的并不是固定的公网IP&#xff0c;而是会定期变化的。为了免受…

中间件之异步通讯组件RabbitMQ入门

一、概述 微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中&#xff0c;调用者发起请求后需要等待服务提供者执行业务返回结果后&#xff0c;才能继续执行后面的业务。也就是说调用者在调用…

解决IDEA下springboot项目打包没有主清单属性

1.问题出现在SpringBoot学习中 , 运行maven打包后无法运行 报错为spring_boot01_Demo-0.0.1-SNAPSHOT.jar中没有主清单属性 SpringBoot版本为 2.6.13 Java 版本用的8 解决方法 1.执行clean 删除之前的打包 2.进行打包规范设置 2.1 3.进行问题解决 (借鉴了阿里开发社区) 使用…

OpenCV(二)—— 车牌定位

从本篇文章开始我们进入 OpenCV 的 Demo 实战。首先&#xff0c;我们会用接下来的三篇文章介绍车牌识别 Demo。 1、概述 识别图片中的车牌号码需要经过三步&#xff1a; 车牌定位&#xff1a;从整张图片中识别出牌照&#xff0c;主要操作包括对原图进行预处理、把车牌从整图…