我有一个从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()时调用基础的keyPressEvent())
但是,子项的closeEvent()将关闭应用程序,而无需在实现中调用基础的closeEvent()。好像它传播到其他地方。
是什么原因导致的? QCloseEvent是否已经传播到其他小部件,即使已经处理过?
最佳答案
真是个好问题。 (我从未想过。)
在引起好奇之后,我进行了一些调查。这对OpenSource软件非常有用–如果您有疑问,请查看源代码。因此,我对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);
(当前在line 634中)。
再次单击,然后进入qwidget.cpp:9936:
void QWidget::closeEvent(QCloseEvent *event)
{
event->accept();
}
嗯是的
这很好地解释了为什么调用基类方法
QMainWindow::closeEvent(event);
就像一个简单的调用一样
event->accept();
甚至两者兼而有之。
虽然,我更喜欢基类事件处理程序的调用。
我认为这是一般有用的经验法则(或成语?):
当然,这是一般的经验法则,应根据必须处理的特定事件进行重新检查。
(如果有疑问,仍然还有woboq.org ...)