必须调用qapplication::exec(),否则窗口不显示且程序立即退出;需正确配置qt模块、moc处理及show()调用顺序。

main()里必须调用QApplication::exec()
没有 QApplication::exec(),窗口不会显示,程序会立即退出。Qt 的事件循环靠它驱动,不是“可选”而是“必须”。常见错误是只写了 QMainWindow 实例、show(),却漏掉这句:
int main(int argc, char *argv[]) {
QApplication app(argc, argv); // 注意:必须在栈上或静态创建
QMainWindow w;
w.show();
return app.exec(); // ← 这行不能少,也不能写成 app.exec(); 单独一行后不 return
}
- 如果
app.exec()放在w.show()前,窗口仍能显示(因为 show() 不阻塞),但逻辑反直觉,不推荐 - 在 Windows 上漏掉
exec()可能表现为黑窗口闪退;Linux/macOS 下进程直接结束,终端无报错 - 多线程中不能在非主线程调用
exec()—— Qt GUI 必须在主线程运行
头文件和 CMakeLists.txt 缺一不可
Qt6 起默认不自动链接 QtWidgets 模块,仅 #include <qmainwindow></qmainwindow> 不够,还必须显式启用模块。否则编译报错:error: 'QMainWindow' was not declared in this scope 或更隐蔽的 undefined reference to vtable。
对应两处要检查:
- 源文件开头需包含
#include <qapplication></qapplication>和#include <qmainwindow></qmainwindow>(Qt6 中QMainWindow不再隐式包含QWidget) -
CMakeLists.txt中必须有:find_package(Qt6 REQUIRED COMPONENTS Core Widgets) target_link_libraries(your_target PRIVATE Qt6::Core Qt6::Widgets)
- Qt5 用户注意:把
Qt6全部换成Qt5,且find_package后加REQUIRED更稳妥,避免静默降级
show() 和 showMaximized() 的行为差异影响启动体验
调用 w.show() 是标准做法,但新手常误用 w.showMaximized() 导致窗口无法还原、任务栏图标异常,尤其在多屏或高 DPI 环境下。
立即学习“C++免费学习笔记(深入)”;
-
show():按 widget 自身尺寸(或默认大小)显示,尊重系统窗口管理器策略 -
showMaximized():强制最大化,但若窗口尚未设置 geometry 或未调用resize(),可能拉伸变形或遮挡任务栏 - 更稳妥的做法是先
resize(800, 600)再show();如需默认最大化,改用w.setWindowState(Qt::WindowMaximized)+w.show() - Qt6.5+ 中,
showFullScreen()和showMaximized()在 Wayland 下行为受限,优先测试目标平台
qmake 和 CMake 生成的 moc 文件容易被忽略
只要类里用了 Q_OBJECT 宏(比如自定义继承 QObject 的类),就必须经过 moc(Meta-Object Compiler)处理。否则链接时报错:undefined reference to `vtable for MyClass'。
- CMake 用户:确保
set(CMAKE_AUTOMOC ON)已开启,且源文件(.cpp)被target_sources()正确包含;moc_*.cpp 会自动生成到 build 目录 - qmake 用户:.pro 文件里要有
QT += widgets,且源文件名不能含空格或中文,否则 moc 可能跳过 - 手动 moc:不推荐,但调试时可用
moc myclass.h -o moc_myclass.cpp查看输出,确认信号槽声明是否被识别
真正卡住人的往往不是语法,而是这些“看不见”的构建环节 —— moc 没跑、模块没连、exec 没调,三者任一缺失,窗口都不会出来。










