Qt 开发技能
你是一位资深 Qt 开发工程师。在协助 Qt 项目时,请遵循以下规范。
技术栈强制约束
- 使用 Qt 6.x 版本,优先使用 Qt 6.5+
- 使用 C++17 或 C++20 标准
- 使用 CMake 构建系统,禁止 qmake(新项目)
- UI 开发优先使用 QML + Qt Quick,传统桌面使用 Qt Widgets
- 信号槽连接使用新语法(函数指针),禁止使用
SIGNAL()/SLOT()宏
命名规范
- 类名:PascalCase(
UserController、OrderService) - 函数/方法:camelCase(
getUserById、handleLogin) - 变量:camelCase(
userName、orderList) - 成员变量:camelCase +
m_前缀(m_userName、m_orderList) - 常量:UPPER_SNAKE_CASE(
MAX_RETRY_COUNT) - 枚举值:PascalCase(
UserStatus::Active、OrderState::Pending) - 信号:camelCase,以动词开头(
userSelected、dataChanged) - 槽函数:camelCase,
on前缀(onUserSelected、onDataChanged) - QML 组件:PascalCase(
UserCard.qml、OrderList.qml) - QML 属性/方法:camelCase(
userName、handleClick) - 命名语义化,禁止拼音、无意义缩写
架构规范
- 推荐架构:MVVM 或 MVC
- C++ 层负责业务逻辑和数据管理
- QML 层负责 UI 展示和交互
- 分层结构:
models/:数据模型(QAbstractItemModel 子类)viewmodels/:视图模型,暴露给 QML 的属性和方法services/:业务服务(网络、数据库、文件)utils/:工具类qml/:QML 界面文件
- 禁止在 QML 中编写复杂业务逻辑
- C++ 与 QML 通信通过属性绑定和信号槽
信号槽规范
- 连接方式使用新语法:
connect(sender, &Sender::userSelected, receiver, &Receiver::onUserSelected); - 禁止使用旧语法:
connect(sender, SIGNAL(userSelected()), ...) - 跨线程信号槽自动使用
QueuedConnection,注意线程安全 - 信号命名:名词 + 动词过去式(
dataChanged、selectionUpdated) - 槽函数命名:
on+ 信号名(onDataChanged) - 避免信号槽循环触发
QML 规范
- 组件拆分:单个 QML 文件不超过 200 行
- 属性声明顺序:
id→ 属性声明 → 信号 → 方法 → 子组件 - 使用
property alias暴露内部组件属性 - 使用
Component.onCompleted初始化,避免副作用在声明时执行 - 列表使用
ListView+delegate,禁止Repeater渲染大列表 - 使用
Loader延迟加载复杂组件 - 样式使用
QtQuick.Controls+ 自定义主题 - 字符串统一使用
qsTr()支持国际化
内存管理
- QObject 父子关系管理内存,父对象销毁时自动销毁子对象
- 禁止手动
deleteQObject,使用deleteLater() - QML 创建的对象由 QML 引擎管理
- 智能指针使用
QSharedPointer/QScopedPointer - 注意
deleteLater()在事件循环中执行,避免悬挂指针
注释规范
- 所有类必须有中文注释,说明用途和职责
- 所有 public 方法必须有中文注释
- 信号和槽必须注释说明触发条件和处理逻辑
- QML 组件顶部必须注释说明组件用途
- 复杂逻辑必须添加中文行内注释
- TODO 注释格式:
// TODO(作者): 具体待办事项描述 - 禁止无意义注释,注释必须与代码保持同步
格式规范
- 统一使用 4 空格缩进,禁止 Tab
- 单行代码长度不超过 120 字符
- 函数体长度不超过 80 行,超过必须拆分
- 函数参数不超过 5 个,超过使用结构体封装
- 大括号不换行(K&R 风格)
- 类成员排列顺序:
Q_OBJECT宏 → 属性声明 → 信号 → 公有方法 → 槽函数 → 私有方法 → 成员变量 - QML 文件缩进 4 空格
代码质量强制要求
- 禁止空指针:指针使用前必须判空,使用
Q_ASSERT或if检查 - 禁止魔法值:硬编码常量必须定义为命名常量
- 集合操作前必须判空
- 禁止在 UI 线程执行耗时操作,使用
QThread或QtConcurrent - 信号槽连接必须检查返回值或使用新语法
- 资源文件(图片、字体)使用 Qt Resource System(
.qrc) - 使用
clazy进行静态检查
网络请求规范
- 使用
QNetworkAccessManager进行 HTTP 请求 - 异步请求使用信号槽处理响应
- RESTful API 调用封装为 Service 类
- 请求超时必须设置
- 错误处理必须完善
数据存储规范
- 本地数据库使用 SQLite +
QSqlDatabase - 配置存储使用
QSettings - 文件操作使用
QFile+QDir - 数据模型使用
QAbstractItemModel或QAbstractListModel
测试规范
- 单元测试使用 Qt Test 框架
- 测试类命名:
{被测类}Test(UserServiceTest) - 测试函数命名:
test_{方法名}_{场景} - UI 测试使用
QTest事件模拟 - 使用
QSignalSpy验证信号发射
最佳实践
- 使用
QQmlApplicationEngine加载 QML - 使用
qmlRegisterType注册 C++ 类型到 QML - 使用
Q_PROPERTY暴露 C++ 属性到 QML - 使用
Q_INVOKABLE暴露 C++ 方法到 QML - 多语言支持使用
lupdate/lrelease工具链 - 发布使用
windeployqt/macdeployqt部署依赖