首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Qt中捕获异常?

如何在Qt中捕获异常?
EN

Stack Overflow用户
提问于 2012-04-09 15:47:01
回答 3查看 34.7K关注 0票数 28
代码语言:javascript
复制
try
{  // `count()` throws exception
  connect(thread, SIGNAL(started()), engine, SLOT(count()));  
}
catch(const X& e)
{}

从Qt-5开始,我得到以下错误:

Qt捕获了从事件处理程序抛出的异常。Qt中不支持从事件处理程序抛出异常。您不能让任何异常通过Qt代码传播。如果这是不可能的,那么在Qt 5中,您至少必须重新实现QCoreApplication::notify()并捕获那里的所有异常。

如果我不能像上面所示的那样以常规的方式捕获异常,那么我们应该在哪里捕获这些异常呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-09 16:30:03

,我应该在哪里抓到它?

这正是Qt不支持跨信号/时隙连接抛出异常的原因。如果你试一试,你会看到这样的信息:

Qt捕获了从事件处理程序抛出的异常。Qt中不支持从事件处理程序抛出异常。您必须重新实现QApplication::QApplication(),并捕获那里的所有异常。

正如它所提到的,可以将QApplication子类并在那里捕获异常,但这将是一种非常烦人的处理方法。

如果可能的话,我建议重写计数,这样就不会抛出。

如果不能重写()怎么办?

例如,如果count()是您正在使用的第三方库中函数的一部分,那么怎么办?

在任何正式的Qt库中都不会抛出任何一个插槽,所以如果您使用的是一个第三方库,并且有一个抛出的槽,这可能是一个迹象,表明它不是一个好的库。如果您想无论如何使用它,我建议您不要在QApplication::notify中捕获它,而是创建一个适配器。

那是什么意思?首先,创建一个在构造函数中接受您粗略的第三方对象的对象。在其中,编写一个用try/catch块封装对抛出槽的调用的槽。现在,不要连接到粗略的第三方对象的插槽,而是连接到新创建的对象的插槽。

通过这种方式执行异常捕获将相关代码保持在一起,并防止QApplication::notify在遇到多个这些问题函数时填充一堆不相关的try/catch块。

例如:

代码语言:javascript
复制
class BadCounter {
Q_OBJECT
public slots:
  void count() { throw CounterError("unable to count"); }
};

class CounterAdaptor {
Q_OBJECT
  BadCounter* counter_;
public:
  CounterAdaptor(BadCounter* counter) {
    counter_ = counter;
  }
public slots:
  void count() {
    try {
      counter_->count();
    } catch (const CounterError& e) {
      std::cerr << e.what() << std::endl;
    }
  }
};

int main() {
  BadCounter engine;
  CounterAdaptor adaptor(&engine);
  QThread* thread = new QThread();
  connect(thread,SIGNAL(started()),&adaptor,SLOT(count())); 
  thread.start();
  ... // etc...
  delete thread;
}

,如果你想处理可以从任何地方抛出的东西怎么办?

这种全球关注的明显例子是一个意外的例外。错误在任何地方都可能发生。最好记录尽可能多的关于事件的细节,以便找出原因并加以纠正。在本例中,您希望在自己的子类中重新实现QApplication::notify,如jichi's answer所示。对全局关注点使用全局处理程序是非常合理的。

票数 21
EN

Stack Overflow用户

发布于 2013-02-11 01:29:42

如果有人需要一个示例代码来覆盖QApplication::QApplication,我从这里获得了一个示例代码(日语):http://www.02.246.ne.jp/~torutk/cxx/qt/QtMemo.html

代码语言:javascript
复制
#include "MyApplication.h"
#include <exception>

MyApplication::MyApplication(int& argc, char** argv) :
  QApplication(argc, argv) {}

bool MyApplication::notify(QObject* receiver, QEvent* event) {
  bool done = true;
  try {
    done = QApplication::notify(receiver, event);
  } catch (const std::exception& ex) {
    // ログや何らかの回復処理
  } catch (...) {
    // ログや何らかの回復処理
  }
  return done;
} 
票数 16
EN

Stack Overflow用户

发布于 2012-04-09 15:59:59

您可以尝试这个示例,以确保您的解决方案是好的:

代码语言:javascript
复制
int f()
{
    throw 1;
    return 5;
}

void g(int x)
{
    cout << x << endl;
}

int main()
{
    try {
            g(f());
    }catch(int)
    {
        cout << "Caught exception" << endl;
    }
}
票数 -12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10075792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档