Qt/C++ 事件循环异常处理

Posted

技术标签:

【中文标题】Qt/C++ 事件循环异常处理【英文标题】:Qt/C++ event loop exception handling 【发布时间】:2010-04-28 12:35:40 【问题描述】:

我有一个基于 QT 和许多第三方库的应用程序。在某些情况下,这些碰巧会引发一些异常。

在原生 Qt 应用程序中,这会导致应用程序中止或终止。通常主数据模型仍然完好无损,因为我将它保存在没有外部数据的纯 Qt 中。

所以我认为我也可以通过告诉用户在此过程中发生错误并且他应该立即保存甚至决定继续处理主模型来恢复。

目前程序只是默默地退出,甚至没有讲故事。

【问题讨论】:

我想我不明白你在问什么。在某个地方,您需要有代码来处理 Qt 和这些其他库之间的交互。在那里进行错误处理和恢复。 (是的,我知道可能有很多很多地方。) 嗨 Caleb,感谢您的评论,我已经尝试过了,但是另一个库只是在程序遇到异常之前中止并终止程序。与此同时,我安装了一个异常处理程序,只要抛出异常就会恢复。不幸的是,第三方库似乎在立即中止之前捕获了异常。调试器只告诉我第三方代码中的访问冲突。 @Georg,你现在可能已经明白了。我正在为可能有同样问题的其他人发帖。在 C++ 访问冲突和除以 0 时不会抛出异常(至少正常情况下)。一旦发生这两种错误中的一种,程序就会立即终止。 【参考方案1】:

有时很难捕获所有异常。如果一个异常意外漏掉,下面的帮助会很大。从QApplication继承并通过以下方式覆盖notify()函数

bool MyApplication::notify( 
QObject * receiver, 
QEvent *  event ) 

    try 
    
        return QApplication::notify(receiver, event);
    
    catch(...)
    
        assert( !"Oops. Forgot to catch exception?" );

        // may be handle exception here ...
    

    return false;

然后将 main() 函数中的 QApplication 替换为您的自定义类。所有的eventsslots都是通过这个函数发出的,这样所有的异常都可以被捕获,你的应用就变得稳定了。

【讨论】:

【参考方案2】:

正如 Qt 文档here 中所述,Qt 目前还不是完全的异常安全的。该页面上的“从异常中恢复”部分描述了在抛出异常时您可以在 Qt 应用程序中执行的唯一操作 - 清理并退出应用程序。

鉴于您正在使用会引发异常的第三方库,您需要在外部库和 Qt 代码之间的边界捕获这些异常,并在那里处理它们 - 正如 Caleb 的评论中所述。如果错误必须传播到 Qt 应用程序中,则必须通过返回错误代码(如果可能)或通过发布事件来完成。

【讨论】:

感谢您的评论,我重新实现了 QApplication::notify() 并捕获了那里的所有内容。这非常好,因为应用程序不只是简单地退出,而是允许用户至少现在保存他的数据。我已经通过从我的代码中抛出异常 std::bad_alloc 等来测试这一点。此外,我从 try catch(...) 内部调用第三方库的代码,但没有任何反应,应用程序崩溃了。

以上是关于Qt/C++ 事件循环异常处理的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试添加第二个活动时未处理的事件循环异常

为啥我在使用 javascript 自动完成时在 Eclipse 中收到消息:“未处理的事件循环异常 Java 堆空间”?

WSO2工具(eclipse)错误未处理的事件循环异常:带有groovy脚本的脚本调解器

前端—— JavaScript基础操作:if语句for循环while循环for...infor...of异常处理函数事件JS选择器JS操作页面样式

PyQt 事件循环和 ipython 中的异常

js 基础 -- 循环函数调用 全局和局部变量异常捕获事件