必须先执行“清理所有项目”删除旧moc/ui文件,再手动运行qmake更新构建配置,最后执行“重新构建”强制全量编译,三步缺一不可;同时需确保.ui文件已保存且构建套件匹配。

改完 UI 或代码后报“找不到槽函数”或“moc_文件里还有旧名字”,直接清理 + 重新构建就能解决,但顺序和细节不对会白忙活。
清理项目必须先删 moc 文件
Qt 的 moc(Meta-Object Compiler)会把 ui 文件和 Q_OBJECT 类的信号槽声明转成 C++ 代码,生成像 moc_mainwindow.cpp 这样的文件。这些文件不会自动更新——哪怕你把按钮的 objectName 从 pushButton_5 改成 btn_submit,旧的 moc 文件还在用老名字,编译时就报错。
- 必须执行“清理所有项目”(
Clean All),不是只点“构建”或“运行” - 快捷键是
Ctrl + Shift + B(Windows/Linux)或Cmd + Shift + B(macOS) - 清理后检查构建目录(比如
build-MyApp-Desktop_Qt_6_7_0_MinGW_64_bit-Debug),确认里面没有moc_*.cpp和ui_*.h文件残留
qmake 必须在重新构建前手动触发
清理完只是清掉了中间文件,但 Qt 的构建系统(尤其是 qmake 项目)不会自动重跑 qmake。如果 .pro 文件没变、.ui 却改了 objectName,或者头文件加了新槽函数,不重跑 qmake 就直接构建,它还是会按旧规则生成 Makefile,导致 moc 步骤跳过或出错。
- 顶部菜单:构建 → 执行
qmake(qmake 项目)或“重新配置 CMake”(CMake 项目) - Qt 6 + CMake 项目容易忽略这步,误以为“清理+构建”就够了
- 如果项目用了影子构建(Shadow Build),确保
qmake步骤的目标路径和当前构建目录一致,否则生成的 Makefile 不会被后续make读到
重新构建 ≠ 构建 + 运行
很多人点“构建”(Build)以为万事大吉,其实这是增量编译——只编译改过的 .cpp,不碰 moc 和 ui 头文件。真正需要的是“重新构建”(Rebuild All),它强制全量编译,包括重新调用 moc 和 uic。
- 快捷键:
Ctrl + Shift + R(Windows/Linux)或Cmd + Shift + R(macOS) - 注意:不要在没清理、没 run qmake 的情况下直接点“重新构建”,它会复用旧的 moc 文件,错误照旧
- 如果用了子项目(
SUBDIRS),要确保主项目设置了CONFIG += ordered,否则依赖顺序错乱,库还没编译完就去编译 GUI 项目,也会报符号未定义
最容易被忽略的是:改完 .ui 文件里的 objectName 后,不保存(Ctrl + S)就去清理构建,Qt Designer 实际没把变更写入 XML;或者清理时选错了构建套件(Kit),结果清的是 Debug 目录,却在 Release 模式下构建——这两处一漏,前面所有步骤都白做。











