事情是這樣的:今天調試窗體,突然發現按ESC鍵居然跳過closeEvent()關閉了對話框!我的關閉判斷都在closeEvent()裡,這直接導緻非正常關閉了正在進行的工作。先重建下場景:
調用處:
{
Corpus corpusDialog(this);
corpusDialog.exec();
}
典型的模态對話框,因為用了exec()。Corpus對話框類中覆寫了closeEvent(),其中父類的closeEvent()為虛函數。這樣,當我按ESC關閉對話框就出現了如題情景。
後來發現,居然是因為Corpus類中沒有覆寫reject()函數導緻的!由Qt官方文檔:
Escape Key
If the user presses the Esc key in a dialog, QDialog::reject() will be called. This will cause the window to close: The close event cannot be ignored.
得知按ESC預設調用的是reject()函數。由于Corpus類中沒有覆寫,直接調用了父類QDialog的reject()。調用QDialog的reject()會發生什麼呢?
它實際調用了done(QDialog::Reject)(同樣由于沒有被覆寫,調用的是QDialog的done)。由Qt官方文檔:
void QDialog::done ( int r ) [virtual slot]
Closes the dialog and sets its result code to r. If this dialog is shown withexec(), done() causes the local event loop to finish, and exec() to return r.
看不出done()到底做了些什麼。調試跟蹤了一圈,發現就我這種情況來講,
- done(QDialog::Reject)僅hide了對話框,
- 然後設定了exec()傳回值為QDialog::Reject,
- 關閉窗體事件循環(這個看不出,估計的),
- 釋放finished(QDialog::Reject)信号,
- 最後釋放rejected()信号。
的卻沒有關閉窗體呀,是以也不會觸發closeEvent()。我應當在Corpus類中覆寫掉reject(),由reject()調用close()。這樣就把問題解決了!
void Corpus::reject()
{
close();
}
轉自:https://www.cnblogs.com/codingmylife/archive/2010/04/29/1724571.html