繁体   English   中英

QCloseEvent 如何传播?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM