我有一个从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()会关闭应用程序,而不调用base的closeEvent()。似乎它传播到了其他地方。
为什么会发生这种情况?QCloseEvent是否会在被处理后传播到其他小组件?
多么好的问题。我从来没有想过这个问题)。
这引起了我的好奇心后,我调查了一下。这就是开源软件的好处--如果你有疑问,只要看看源代码就可以了。所以,我在 woboq.org:
首先,我找的是 closeEvent()
在 qmainwindow.cpp 但我找不到它的任何地方。
同样在 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();
}
啊,yepp。
这就很好地解释了为什么调用基类的方法
QMainWindow::closeEvent(event);
和简单的调用
event->accept();
甚至两者都有。
虽然,我更倾向于调用基类的事件处理程序。
我认为这是一般有用的经验法则(或者说是习惯用语?
如果基类的行为应该是 延长 然后在你的重载中调用基类事件处理程序。
如果基类的行为应该是 取代 那么就不要调用基类事件处理程序。
当然,这只是一般的经验法则,应该根据需要处理的具体事件重新检查。
(如果有疑问的话,还有 woboq.org...)