天天看點

Qt按ESC關閉模态對話框不觸發closeEvent()問題解析(轉)

事情是這樣的:今天調試窗體,突然發現按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

繼續閱讀