QCloseEvent如何传播?

问题描述 投票:1回答:1

我有一个从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是否会在被处理后传播到其他小组件?

c++ qt qtwidgets
1个回答
1
投票

多么好的问题。我从来没有想过这个问题)。

这引起了我的好奇心后,我调查了一下。这就是开源软件的好处--如果你有疑问,只要看看源代码就可以了。所以,我在 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...)

© www.soinside.com 2019 - 2024. All rights reserved.