[英]How does a QCloseEvent propagate?
我有一個從 QMainWindow 派生的 MainWindow,並且我重新實現了 closeEvent() 處理程序。
void MainWindow::closeEvent(QCloseEvent *event)
{
if (this->okToContinue()) {
this->writeSettings();
//event->accept();
QMainWindow::closeEvent(event); // will work just fine even if this line omitted
} else {
event->ignore();
}
}
我已經注釋掉了 QMainWindow::closeEvent() 以測試應用程序將退出,而事件不會傳播到基本實現。 奇怪的是,它確實退出了。
我可以將 event->ignore() 放在 if-else 語句之外以防止退出,但這不是重點。
其他事件處理程序(例如 keyPressEvent() 在其覆蓋中沒有基本實現的情況下無法正常工作,但 closeEvent() 確實在沒有基本實現的情況下工作。 (當然,除非您重新實現所有內容)
void LineEdit::keyPressEvent(QCloseEvent *event)
{
QLineEdit::keyPressEvent(event); // will not show text in the widget if omitted
}
根據我在文檔中收集的內容,一旦一個小部件處理了一個事件,它就不會進一步傳播,除非明確允許。 (即在孩子的keyPressEvent()的實現中調用base的keyPressEvent())
然而,孩子的 closeEvent() 將關閉應用程序,而不會在其實現中調用基礎的 closeEvent()。 似乎它傳播到其他地方。
是什么導致這種情況發生? QCloseEvent 即使在它已經被處理之后也會傳播到其他小部件嗎?
多么好的問題。 (我從來沒有想過這個。)
這引起了我的好奇心,我調查了一下。 這就是開源軟件的好處——如果您有疑問,只需查看源代碼。 所以,我在woboq.org上挖掘了一下:
首先我在qmainwindow.cpp中尋找closeEvent()
但我在任何地方都找不到它。
在qmainwindow.h中也是如此。
所以,我假設QMainWindow
不會覆蓋closeEvent()
。
QMainWindow
是從QWidget
派生的,可以在文檔中輕松找到。 或直接在我手頭的源代碼中:
class Q_WIDGETS_EXPORT QMainWindow : public QWidget
因此,我切換到qwidget.h聲明
virtual void closeEvent(QCloseEvent *event);
(目前在第 634 行)。
再次單擊,我進入qwidget.cpp :9936 :
void QWidget::closeEvent(QCloseEvent *event)
{
event->accept();
}
啊,是的。
這很好地解釋了為什么調用基本 class 方法
QMainWindow::closeEvent(event);
工作以及一個簡單的調用
event->accept();
甚至兩者兼而有之。
不過,我更喜歡調用基本的 class 事件處理程序。
我認為這是一般有用的經驗法則(或成語?):
如果應擴展基本 class 的行為,則在您的覆蓋中調用基本 class 事件處理程序。
如果應替換基本 class 的行為,則不要調用基本 class 事件處理程序。
當然,這是一般的經驗法則,應根據必須處理的特定事件重新檢查。
(如果有疑問,仍然有woboq.org ...)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.