CMake实战指南一:add_custom_command
CMake 进阶:add_custom_command 用法详解与实战指南
在 CMake 构建系统中,add_custom_command 是一个灵活且强大的工具,允许开发者在构建流程中插入自定义操作。无论是生成中间文件、执行预处理脚本,还是在目标构建前后触发额外逻辑,它都能轻松胜任。本文将从基础语法、核心参数、实战案例到高级技巧,全面解析 add_custom_command 的用法。
一、为什么需要 add_custom_command?
CMake 的核心优势在于跨平台构建,但默认流程难以覆盖所有个性化需求。例如:
- 生成动态配置文件(如根据编译选项生成 config.h)
- 集成外部工具链(如代码生成器、静态分析工具)
- 构建后处理(如复制可执行文件到部署目录、生成版本号)
- 复杂依赖管理(非传统文件依赖的场景)
add_custom_command 正是为解决这类问题而生,它通过在构建流程中注入自定义命令,让 CMake 具备更强的扩展性。
二、基础语法与核心参数
2.1 两大使用场景
场景 1:生成文件(File Generation)
用于定义 “输入文件→输出文件” 的映射关系,CMake 会根据依赖自动触发命令:
add_custom_command( OUTPUT <output1> [<output2>...] # 必选:命令生成的目标文件 COMMAND <command1> [<args1>...] # 必选:执行的命令(可多条) [MAIN_DEPENDENCY <file>] # 主依赖文件(变化时强制重新执行) [DEPENDS <dep1> <dep2>...] # 附加依赖文件/目标(变化时触发重新执行) [IMPLICIT_DEPENDS <lang> <file>] # 隐式依赖(如语法分析生成的依赖) [WORKING_DIRECTORY <dir>] # 命令执行的工作目录(默认当前源目录) [COMMENT "<message>"] # 执行时显示的提示信息 [VERBATIM] # 保留命令原始格式(避免CMake转义) [USES_TERMINAL] # 在终端中执行命令(Windows适用) ) |
场景 2:关联构建目标(Target Hook)
用于在目标(可执行文件 / 库)的构建阶段插入钩子:
add_custom_command( TARGET <target_name> # 必选:关联的目标(如add_executable生成的目标) PRE_BUILD | PRE_LINK | POST_BUILD # 必选:命令执行时机(编译前/链接前/构建后) COMMAND <command> [<args>...] # 执行的命令(可多条) [WORKING_DIRECTORY <dir>] # 工作目录 [COMMENT "<message>"] # 提示信息 [VERBATIM] # 禁用参数转义 ) |
2.2 核心参数解析
参数 | 说明 |
OUTPUT | 必选(场景 1),指定命令生成的文件,CMake 通过检查这些文件是否存在决定是否执行命令 |
COMMAND | 必选,支持多条命令(按顺序执行),可使用 CMake 变量(如 ${CMAKE_CURRENT_BINARY_DIR}) |
DEPENDS | 显式依赖,支持文件路径或目标名称(如add_executable生成的目标),依赖变化时触发重跑 |
MAIN_DEPENDENCY | 主依赖,优先级高于DEPENDS,仅当该文件变化时才强制重新生成输出文件 |
IMPLICIT_DEPENDS | 隐式依赖(如通过语法分析推导的依赖),需指定语言类型(如CXX、C) |
VERBATIM | 关键参数!确保命令中的特殊符号(如$、#)不被 CMake 解析,避免语法错误 |
三、实战案例:从基础到进阶
3.1 案例 1:生成编译期配置文件
需求:根据 CMake 选项生成 config.h,包含版本号和编译参数。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(add_custom_command02 VERSION 1.0.0) # 定义配置模板
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h
) # 使用 add_custom_command 生成动态内容
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/build_info.txtCOMMAND ${CMAKE_COMMAND} -E echo %PATH% >> ${CMAKE_CURRENT_BINARY_DIR}/env.txtCOMMAND ${CMAKE_COMMAND} -E echo "Build Time: %DATE% %TIME%" >> ${CMAKE_CURRENT_BINARY_DIR}/build_info.txtCOMMAND ${CMAKE_COMMAND} -E echo "Version: ${PROJECT_VERSION}" >> ${CMAKE_CURRENT_BINARY_DIR}/build_info.txtCOMMENT "Generating build information"VERBATIM
)# 添加自定义目标,确保配置文件在编译前生成
add_custom_target( generate_config ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/config.h ${CMAKE_CURRENT_BINARY_DIR}/build_info.txt
) # 关联到可执行文件,确保依赖正确
add_executable(add_custom_command01 src/main.cpp)
target_include_directories(add_custom_command01 PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
// 以下是 main.cpp 代码示例
#include <iostream>
#include "config.h"int main()
{std::cout << "Project Version: " << PROJECT_VERSION << std::endl;std::cout << "Build Time: " << __DATE__ << " " << __TIME__ << std::endl;return 0;
}
// 以下是 config.h.in 示例内容,可根据实际需求定义更多宏或变量
#ifndef CONFIG_H_IN
#define CONFIG_H_IN#define PROJECT_VERSION "@PROJECT_VERSION@"#endif
编译工程完毕后执行命令生成的文件
关键点:
- 通过 configure_file 处理模板文件,结合 add_custom_command 生成动态内容
- add_custom_target 定义独立构建目标,ALL 关键字使其在默认构建时触发
3.2 案例 2:构建后自动部署
-
需求:将可执行文件和依赖库复制到指定部署目录,并生成版本清单。
cmake_minimum_required(VERSION 3.16)
project(DeploymentDemo) # 添加头文件路径(当前源目录)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) # 生成可执行文件
add_executable(DeploymentDemo src/main.cpp src/utils.cpp
) # 构建后部署命令(兼容Windows/Linux)
add_custom_command( TARGET DeploymentDemo POST_BUILD # 创建部署目录(跨平台路径) COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/deploy" # 复制可执行文件(使用生成器表达式获取路径) COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:DeploymentDemo>" "${CMAKE_CURRENT_BINARY_DIR}/deploy" # 复制动态库(Windows示例,Linux可忽略或使用cp命令) COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:DeploymentDemo>" "${CMAKE_CURRENT_BINARY_DIR}/deploy" # 生成版本清单 COMMAND ${CMAKE_COMMAND} -E echo "Version: ${PROJECT_VERSION}" > "${CMAKE_CURRENT_BINARY_DIR}/deploy/VERSION.txt"VERBATIM
)
main.cpp代码
#include <iostream>
#include "utils.h" int main() { std::cout << "Main program running." << std::endl; printDeploymentInfo(); // 调用部署信息函数 return 0;
}
// 假设这里有一个简单的辅助函数声明在 utils.h 中,实现于 utils.cpp,用于打印一些部署信息
// utils.h
#ifndef UTILS_H
#define UTILS_Hvoid printDeploymentInfo();#endif
// utils.cpp
#include <iostream>
#include "utils.h"void printDeploymentInfo()
{std::cout << "Deployment completed successfully." << std::endl;
}
编译工程完毕后执行命令生成的文件
关键点:
- POST_BUILD 时机确保在目标构建完成后执行
- $<TARGET_FILE:target> 生成器表达式动态获取目标文件路径
- copy_if_different 避免重复复制,提升构建效率
高级技巧与最佳实践
4.1 动态生成命令参数
利用 CMake 的变量和生成器表达式,使命令参数动态化:
# 根据系统架构选择不同的处理脚本
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/arch_info.txt COMMAND ${CMAKE_COMMAND} -E echo "Architecture: $<IF:$<BOOL:$<CMAKE_SIZEOF_VOID_P:8>>,x86_64,i386>" >> ${ARCH_INFO_FILE} VERBATIM
)
4.2 处理复杂依赖链
通过 IMPLICIT_DEPENDS 声明隐式依赖(如语法分析生成的依赖):
add_custom_command( OUTPUT parser.cpp parser.h COMMAND bison -d ${CMAKE_CURRENT_SOURCE_DIR}/parser.yy -o ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_BINARY_DIR}/parser.h # 声明C++头文件依赖 VERBATIM
)
4.3 避免循环依赖
确保 add_custom_command 的输出文件不被其依赖的目标直接或间接依赖,例如:
# 错误示例:输出文件作为目标源文件,同时目标依赖自身
add_custom_command(OUTPUT a.txt COMMAND echo "a" > a.txt)
add_executable(bad_target a.txt) # 循环依赖风险!
正确做法:通过 add_custom_target 显式管理依赖关系。
五、常见问题与解决方案
5.1 输出文件路径错误
现象:命令执行后文件未生成到预期目录。解决:
- 使用绝对路径(如 ${CMAKE_CURRENT_BINARY_DIR}/output.txt)
- 通过 WORKING_DIRECTORY 指定命令执行目录
5.2 依赖检测不生效
现象:依赖文件变化后,命令未重新执行。解决:
- 确保 DEPENDS 正确列出所有相关文件
- 对非文件依赖(如环境变量),可添加虚拟依赖文件
5.3 多命令执行顺序混乱
现象:多条 COMMAND 未按顺序执行。解决:
- CMake 保证 COMMAND 按声明顺序执行,无需额外处理
5.4 VERBATIM 的必要性
场景:命令中包含 $、$#$ 等符号时,必须添加 VERBATIM,否则 CMake 会尝试解析为变量或注释,导致错误。
六、总结与推荐用法
使用场景 | 推荐语法 | 核心参数 |
文件生成 | OUTPUT + COMMAND + DEPENDS | VERBATIM, MAIN_DEPENDENCY |
构建阶段钩子 | TARGET + PRE/POST_BUILD | WORKING_DIRECTORY, 生成器表达式 |
复杂依赖管理 | IMPLICIT_DEPENDS | 语言类型(如CXX) |
动态参数生成 | 生成器表达式(如$<TARGET_FILE>) | VERBATIM |
add_custom_command 的灵活性使其成为 CMake 进阶的必备工具,但过度使用可能导致构建逻辑复杂化。建议:
- 优先使用 CMake 内置命令(如configure_file、add_library),仅在必要时引入自定义命令
- 为自定义命令添加清晰的 COMMENT,如上面案例中详细说明每个命令的意图,方便调试
- 通过add_custom_target 集中管理独立的构建步骤
通过合理运用 add_custom_command,开发者可以将 CMake 构建系统与项目的特殊需求深度整合,实现从代码生成到部署的全流程自动化。
如果有具体项目场景或疑难问题,欢迎在评论区交流!
相关文章:
CMake实战指南一:add_custom_command
CMake 进阶:add_custom_command 用法详解与实战指南 在 CMake 构建系统中,add_custom_command 是一个灵活且强大的工具,允许开发者在构建流程中插入自定义操作。无论是生成中间文件、执行预处理脚本,还是在目标构建前后触发额外逻…...
K8S学习之基础七十五:istio实现灰度发布
istio实现灰度发布 上传镜像到harbor 创建两个版本的pod vi deployment-v1.yaml apiVersion: apps/v1 kind: Deployment metadata:name: appv1labels:app: v1 spec:replicas: 1selector:matchLabels:app: v1apply: canarytemplate:metadata:labels:app: v1apply: canaryspec…...
7-1 列出连通集
作者 陈越 单位 浙江大学 给定一个有 n 个顶点和 m 条边的无向图,请用深度优先遍历(DFS)和广度优先遍历(BFS)分别列出其所有的连通集。假设顶点从 0 到 n−1 编号。进行搜索时,假设我们总是从编号最小的顶点…...
XML Schema 指示器
XML Schema 指示器 引言 XML Schema 是一种用于定义 XML 文档结构的语言,它能够确保 XML 文档的合法性。在 XML 文档的解析和应用中,XML Schema 指示器(XML Schema Indicator)扮演着至关重要的角色。本文将详细介绍 XML Schema 指示器的概念、作用、应用场景以及如何使用…...
Linux内核中TCP协议栈的实现:tcp_close函数的深度剖析
引言 TCP(传输控制协议)作为互联网协议族中的核心协议之一,负责在不可靠的网络层之上提供可靠的、面向连接的字节流服务。Linux内核中的TCP协议栈实现了TCP协议的全部功能,包括连接建立、数据传输、流量控制、拥塞控制以及连接关闭等。本文将深入分析Linux内核中tcp_close…...
17-产品经理-创建发布
点击“发布”-“创建发布”。 填写发布名称,选择测试的版本。还可以设置此次发布是否为“里程碑”。 点击“保存”后,进入该发布详情页面。需要为此次发布关联需求、已解决BUG、以及遗留BUG。可以通过设置条件,进行“搜索”,然后批…...
了解Spring的统一功能
目录 一、统一数据返回格式 1.引入统一数据返回格式 2.学习使用统一数据返回格式 support方法 beforeBodyWrite方法 统一数据返回格式具体逻辑 使用统一数据返回格式存在的问题 解决方法: 统一数据返回格式的优点 统一数据返回格式代码实现(包含了…...
123213
根据道路在道路网的地位、交通功能、对沿线的服务功能划分可分为快速路、主干路、次干路及支路 快速路完全为交通功能服务, 主干路以交通功能为主, 次干路是城市区域性的交通干道,为区域交通集散服务,兼有服务功能,结合主干路组成干路网 …...
通过 axios 请求回来的 HTML 字符串渲染到 Vue 界面上并添加样式
1. 通过 axios 获取数据 使用 axios 发起请求,获取返回的 HTML 字符串数据。 2. 在 Vue 中处理和渲染数据 由于 HTML 字符串中可能包含一些标签和样式,直接插入到 Vue 的模板中可能会导致样式问题。可以通过以下方式处理: 方法一…...
P1162 填涂颜色(BFS)
题目描述 由数字 0 组成的方阵中,有一任意形状的由数字 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2。例如:66 的方阵(n6),涂色前和涂色后的方阵如下: 如果从某个 0 出发,只向上下…...
【笔记】VS中C#类库项目引用另一个类库项目的方法
VS中C#类库项目引用另一个类库项目的方法 在 C# 开发中,有时我们需要在一个类库项目中引用另一个类库项目,但另一个项目可能尚未编译成 DLL。在这种情况下,我们仍然可以通过 Visual Studio 提供的项目引用功能进行依赖管理。 🎯 …...
进程内存分布--之smaps呈现memory-layout.cpp内存分布
上一篇介绍了:进程内存分布--之单线程代码来内存分布呈现memory-layout.cpp 这里我们使用smaps将更加形象的的体现内存分布,smaps文件是Linux的proc文件系统提供的一种可以查看内存资源使用情况的方法,Linux系统中运行的库、堆、栈等信息都可在smaps中查…...
再看自适应RAG方法:SEAKR|PIKE-RAG|DeepRAG
当大语言模型开始"怀疑人生":一场关于知识检索的AI内心戏 各位看官,今天我们要聊一个AI界的"哲学难题"——当大语言模型突然意识到自己可能是个"半瓶子醋",会发生什么奇妙反应? 想象一下这个场景:某天深夜,ChatGPT正对着用户提问"如…...
DNS服务(Linux)
DNS 介绍 dns,Domain Name Server,它的作用是将域名解析为 IP 地址,或者将IP地址解析为域名。 这需要运行在三层和四层,也就是说它需要使用 TCP 或 UDP 协议,并且需要绑定端口,53。在使用时先通过 UDP 去…...
探秘PythonJSON解析深度剖析json.loads处理嵌套JSON字符串的奥秘
哈喽,大家好,我是木头左! 在当今数字化时代,数据以各种格式呈现,而JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,在众多领域广泛应用。Python作为一门强大的编程语言,其内置的json模块为处理JSON数据提供了便捷的方法。然而,当遇到像{"name&q…...
Day7 FIFO与鼠标控制
文章目录 1. harib04a例程(获取按键编码)2. harib04b例程(加快中断处理)3. harib04c例程(FIFO缓冲区)4. harib04d例程(改善FIFO缓冲区)5. harib04e例程(整理FIFO缓冲区&a…...
软件工程第一章习题
第1章软件与软件工程 1.选择题 (1)下列说法中正确的是( )o A.20世纪50年代提出了软件工程的概念 B.20世纪60年代提出了软件工程的概念 C.20世纪70年代出现了客户机/服务器技术 D.20世纪80年代软件工程学科达到成熟 (2)软件危机的主要原因是( Do B.软件生产…...
Ollama 手动高速下载Win/Linux/Mac安装包及安装方法
前言 Ollama下载速度太慢,按这个方式,速度嘎嘎的快----下载地址 手动安装 如果要从以前的版本升级,则应删除旧库。比如:sudo rm -rf /usr/lib/ollama 解压 tar -C /usr -xzf ollama-linux-amd64.tgz # 解压到/usr文件夹# 如…...
Jmeter+Jenkins+Ant自动化持续集成环境搭建
一、安装准备 1.JDK:jdk-8u121-windows-x64 2.jmeter工具:apache-jmeter-2.13 3.ANT工具:apache-ant-1.9.7-bin 4.jenkins工具:jenkins-2.32.2 二、软件安装 1.JDK的安装 >双击JDK安装包,选择安装路径(本人是…...
【11】Redis快速安装与Golang实战指南
文章目录 1 Redis 基础与安装部署1.1 Redis 核心特性解析1.2 Docker Compose 快速部署1.3 Redis 本地快速部署 2 Golang 与 Redis 集成实战2.1 环境准备与依赖安装2.2 核心操作与数据结构实践2.2.1 基础键值操作2.2.2 哈希结构存储用户信息 3 生产级应用场景实战3.1 分布式锁实…...
ISP算法.红外图像增强
在图像处理领域,常见的图像处理一般都是白光相机,实际红外相机也是常见的一种相机,它可以用来对发热的东西进行成像,也可以作为白光相机夜晚不可见的一种辅助手段,为白光相机赋能夜视能力。 红外相机的成像原理在于辐射…...
Spring Boot中使用RedisTemplate操作Redis的几种数据类型详解
Redis作为高性能的键值存储系统,在现代Java应用中扮演着重要角色。Spring Boot通过RedisTemplate为开发者提供了便捷的Redis操作方式。本文将详细介绍如何使用RedisTemplate操作Redis的五种主要数据类型。 一、RedisTemplate简介 RedisTemplate是Spring Data Redi…...
大数据与人工智能之大数据架构(Hadoop、Spark、Flink)
一、核心特性与架构设计 1. Hadoop:分布式批处理的基石 核心组件: HDFS:分布式文件系统,支持大规模数据存储。MapReduce:基于“分而治之”的批处理模型,适合离线分析。 架构特点: 批处理主导&…...
VSCode中Marp插件
VSCode神级插件Marp,用Markdown来做PPT 优秀教程:https://zhuanlan.zhihu.com/p/582872955...
C++20 数学常数:<numbers> 头文件的革新
文章目录 一、<numbers> 头文件中的数学常数二、使用示例三、优势与应用场景(一)提高代码可读性(二)提高精度(三)适用于多种数据类型(四)简化数学计算 四、总结 C20 标准引入了…...
OpenCV--图像平滑处理
在数字图像处理领域,图像平滑处理是一项极为重要的技术,广泛应用于计算机视觉、医学影像分析、安防监控等多个领域。在 OpenCV 这一强大的计算机视觉库的助力下,我们能便捷地实现多种图像平滑算法。本文将深入探讨图像平滑的原理,…...
【KMP】P7114 [NOIP2020] 字符串匹配|省选-
本文涉及知识点 较难理解的字符串查找算法KMP P7114 [NOIP2020] 字符串匹配 题目描述 小 C 学习完了字符串匹配的相关内容,现在他正在做一道习题。 对于一个字符串 S S S,题目要求他找到 S S S 的所有具有下列形式的拆分方案数: S A …...
C++20 统一容器擦除:std::erase 和 std::erase_if
文章目录 一、std::erase 的用法1.1 语法1.2 参数1.3 返回值1.4 示例 二、std::erase_if 的用法2.1 语法2.2 参数2.3 返回值2.4 示例 三、优势与应用场景3.1 统一的接口3.2 简化代码3.3 适用范围广 四、总结 C20 引入了两个非常实用的函数模板: std::erase 和 std…...
阿里云oss视频苹果端无法播放问题记录
记录一下苹果端视频不可以播放的原因. 看了一下其他视频可以正常播放,但是今天客户发来的视频无法正常播放.咨询过阿里云售后给出的原因是编码格式过高. 需要调整编码格式为:baseline, 下面记录如何使用ffmpeg修改视频的编码格式. 下载文件(可从官方下载) 配置环境变量(系统变…...
10-MySQL-性能优化思路
1、优化思路 当我们发现了一个慢SQL的问题的时候,需要做性能优化,一般我们是为了提高SQL查询更快,一个查询的流程由下图的各环节组成,每个环节都会消耗时间,要减少消耗时候需要从各个环节都分析一遍。 2 连接配置优化…...
Postman之参数化详解
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 小伙伴们,好久不见呀,今天呢笔者想和大家聊聊postman参数化,在接口测试中,部分参数每次发送请求是唯一的数值&a…...
【c++深入系列】:类和对象详解(下)
🔥 本文专栏:c 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 你的人生剧本,不是父母的续集,不是子女的前传,更不是朋友的外传——你是自己故事的主角 ★★★ 本文前…...
浅谈「分词」:原理 + 方案对比 + 最佳实践
在文本搜索、自然语言处理、智能推荐等场景中,「分词」 是一个基础但至关重要的技术点。无论是用数据库做模糊查询,还是构建搜索引擎,分词都是提高效率和准确度的核心手段。 🔍 一、什么是分词? 分词(Tok…...
第十八:GC 垃圾回收
2.1 三色标记# 灰色:对象已被标记,但这个对象包含的子对象未标记黑色:对象已被标记,且这个对象包含的子对象也已标记,gcmarkBits对应的位为1(该对象不会在本次GC中被清理)白色:对象…...
【微机及接口技术】- 第七章 可编程定时/计数器
文章目录 第一节 定时/计数器的概述一、定时与计数二、定时方法 第二节 可编程定时/计数器8254一、8254-2的基本功能二、8254的内部结构和外部引脚三、8254 的工作方式1. 方式0:计数到零产生中断方式2. 方式1:硬件可重触发单稳方式3. 方式2:速…...
MES生产工单管理系统,Java+Vue,含源码与文档,实现生产工单全流程管理,提升制造执行效率与精准度
前言: MES生产工单管理系统是制造业数字化转型的核心工具,通过集成生产、数据、库存等模块,实现全流程数字化管理。以下是对各核心功能的详细解析: 一、生产管理 工单全生命周期管理 创建与派发:根据销售订单或生产计…...
【区块链安全 | 第三十五篇】溢出漏洞
文章目录 溢出上溢示例溢出漏洞溢出示例漏洞代码代码审计1. deposit 函数2. increaseLockTime 函数 攻击代码攻击过程总结修复建议审计思路 溢出 算术溢出(Arithmetic Overflow),简称溢出(Overflow),通常分…...
【自记录】ubuntu命令行下禁用指定声卡
设备上内置了一块声卡,出于某些原因我希望禁用他。 通过arecord -l可以查看到该设备 $ arecord -l **** List of CAPTURE Hardware Devices **** card 0: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]Subdevices: 1/1Subdevice #0: subdevice…...
设计模式 Day 4:观察者模式(Observer Pattern)深度解析
在经历了前三天的对象创建型设计模式学习之后,今天我们开始进入行为型设计模式的探索之旅。行为型模式聚焦于对象之间的通信机制与协作方式,其中最经典且应用最广泛的就是——观察者模式(Observer Pattern)。本文将用8000字篇幅&a…...
`QTabWidget` 的标签页头设置样式,可以通过在 QSS 文件中定义 `QTabBar::tab` 的样式
要为 QTabWidget 的标签页头设置样式,可以通过在 QSS 文件中定义 QTabBar::tab 的样式来实现。以下是完整的代码示例和 QSS 文件内容,展示如何为标签页头设置背景颜色、文本颜色、悬停效果和选中效果。 ### **代码示例** cpp #include <QApplication…...
低代码开发革命:用 ZKmall开源商城可视化逻辑编排实现业务流程再造
ZKmall开源商城通过可视化逻辑编排引擎与低代码开发范式,重新定义了企业级电商业务流程的构建与优化方式。本文将从技术架构、核心能力、实践案例及行业价值等维度,解析其如何以"低代码流程引擎"组合拳实现业务流程再造的革命性突破。 一、低代…...
CAN外设
目录 1. CAN外设结构 1.1 CAN外设发送流程 1.2 CAN外设接收流程 1.3 发送接受配置位 2. CAN外设过滤器 2.1 过滤器配置 2.2 测试模式 2.3 工作模式 2.4 过滤器对应中断 2.5 错误处理和离线恢复 1. CAN外设结构 以STM32F103为例。以下是它的内部结构框图。 其具体发…...
(七)安卓开发中的状态列表图形(StateListDrawable)详解
在安卓开发中,**状态列表图形(StateListDrawable)**是一种非常实用的资源,它允许开发者根据视图的不同状态(如按下、聚焦、选中等)来动态显示不同的图像或颜色。这种机制在创建交互式用户界面时尤为重要&am…...
2023年蓝桥杯第十四届CC++大学B组真题及代码
目录 1A:日期统计 解析代码_暴力_正解 2B:01串的熵 解析代码_暴力_正解 3C:冶炼金属 解析代码_暴力_正解 4D:飞机降落 解析代码_暴力dfs_正解 5E:接龙数列 解析代码_dp_正解 6F:岛屿个数 解析代…...
odo18实施——销售-仓库-采购-制造-制造外包-整个流程自动化单据功能的演示教程
安装模块 安装销售 、库存、采购、制造模块 2.开启外包功能 在进入制造应用点击 配置—>设置 勾选外包,点击保存 添加信息 一、添加客户信息 点击到销售应用 点击订单—>客户 点击新建 创建客户1,及其他客户相关信息,点…...
c++造轮子之REACTOR实战
本文实现的为单reactor 多线程(base) 非核心库 InetAddress 这个库简单而言 无疑是设置ip地址和端口 class InetAddress { public:struct sockaddr_in addr;socklen_t addr_len;InetAddress();InetAddress(const char* ip, uint16_t port);~InetAddress(); };具体而言: Ine…...
【Easylive】Elasticsearch搜索组件详解
【Easylive】项目常见问题解答(自用&持续更新中…) 汇总版 一、Elasticsearch基础介绍 Elasticsearch(简称ES)是一个分布式、RESTful风格的搜索和分析引擎,基于Apache Lucene构建。在视频平台中,它主要用于: 全…...
基于AT89C51单片机的加减乘除液晶计算机设计
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/90574816?spm1001.2014.3001.5503 功能介绍: 可进行最高四位数的加减乘除运算,除法运算保留小数点后四位;4*4矩阵按键输入&…...
先进制造aps专题三十三 开源aps产品,frepple和dream对比分析
开源的两个aps产品,frepple和dream对比分析 frepple开源的基本不能用,第一它甘特图没开源,而且甘特图不允许你手工个修改,你想把它当成手工甘特图用也不行,第二,算法强制倒排,很少企业是倒排 …...
Vue3.2 项目打包成 Electron 桌面应用
本文将详细介绍如何将基于 Vue3.2 的项目打包成 Electron 桌面应用。通过结合 Electron 和 Vue CLI 工具链,可以轻松实现跨平台桌面应用的开发与发布。 1. 项目结构说明 项目主要分为以下几个部分: electron/main.js:Electron 主进程文件。…...