書中所述:「close() 槽不一定使程序退出,只有當剩下最後一個主界面 (無父視窗) 時調用 close(),程序才會退出;其他情況下界面只是隱藏,並未被銷毀。」
QApplication::exec() 事件循環在以下條件退出:
QWidget 子類實例) 都被關閉/銷毀。QApplication::quit() 或 exit()。QApplication::quit() (由 QApplication::quitOnLastWindowClosed 屬性控制,默認 true)。// main.cpp
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w1; w1.show(); // 主視窗 1
MainWindow w2; w2.show(); // 主視窗 2 (同層級)
// 此時有兩個主視窗
return a.exec();
}
若視窗設置 setAttribute(Qt::WA_DeleteOnClose, false) (默認),close() 只是調用 hide(),視窗對象仍存活於堆/棧上。再次 show() 即可恢復。
常見模式:系統托盤程序 — 主視窗關閉時隱藏到托盤,程序後台持續運行。
void MainWindow::closeEvent(QCloseEvent *event) {
if (trayIcon->isVisible()) {
hide(); // 僅隱藏
event->ignore(); // 忽略關閉事件,不銷毀
} else {
event->accept(); // 允許關閉 (最後一次)
}
}
// 方式 1: 關閉所有視窗
qApp->closeAllWindows(); // 觸發各視窗 closeEvent,最終退出
// 方式 2: 直接退出事件循環
qApp->quit(); // 或 qApp->exit(0);
// 方式 3: 設置屬性 (謹慎使用)
qApp->setQuitOnLastWindowClosed(true); // 默認即為 true
在 main.cpp 添加日誌追蹤視窗生命週期:
qDebug() << "Top level widgets:" << QApplication::topLevelWidgets().count();
QApplication::instance()->setQuitOnLastWindowClosed(true);
close() 行為取決於視窗屬性與當前存活的主視窗數量。理解 頂層視窗計數 是掌握 Qt 程序退出邏輯的關鍵。