如何在Qt中捕获异常? [英] How to catch exceptions in Qt?

查看:7529
本文介绍了如何在Qt中捕获异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

try
{  // `count()` throws exception
  connect(thread, SIGNAL(started()), engine, SLOT(count()));  
}
catch(const X& e)
{}

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

As of Qt-5, I get following error:


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

Qt has caught an exception thrown from an event handler. Throwing exceptions from an event handler is not supported in Qt. You must not let any exception whatsoever propagate through Qt code. If that is not possible, in Qt 5 you must at least re-implement QCoreApplication::notify() and catch all exceptions there.

如果我无法以上述常规方式捕获异常,那么我们应该在哪里捕获这些异常?

If I can't catch the exceptions in conventional way as shown above, then where are we supposed to catch those?

推荐答案


我应该在哪里捕捉它?

where am I supposed to catch it?

这正是Qt不支持跨信号/插槽连接抛出异常的原因。如果尝试使用,则会看到以下消息:

This is exactly why Qt does not support throwing exceptions across signal/slot connections. If you try it, you'll see this message:


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

Qt has caught an exception thrown from an event handler. Throwing exceptions from an event handler is not supported in Qt. You must reimplement QApplication::notify() and catch all exceptions there.

如前所述,有可能子类QApplication并在那里捕获您的异常,但这将是一种非常烦人的处理方式。

As it mentions, it is possible to subclass QApplication and catch your exception there, but that will be a very annoying way of handling things.

如果可能的话,我建议重写count使其不会抛出。

If possible, I would recommend rewriting count such that it does not throw.

如果您无法重写count()怎么办?

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

For example, what if count() is part of a function in a 3rd-party library that you're using?

否任何正式的Qt库抛出的插槽,因此,如果您使用带有抛出异常的插槽的第三方库,则可能表明它不是一个好的库。如果仍然要使用它,我建议您创建一个适配器,而不是在 QApplication :: notify 中捕获它,而不是将其捕获。

No slot in any official Qt library throws, so if you're using a third-party library with a slot that throws, it's probably a sign that it's not a good library. If you want to use it anyway, I recommend that rather than catching it in QApplication::notify, that you instead create an adapter.

是什么意思?首先创建一个对象,该对象将您的粗略第三方对象纳入构造函数中。在其中编写一个插槽,其中使用try / catch块将对调用的调用包装起来。现在,不必连接到草图上的第三方对象的插槽,而要连接到新创建的对象的插槽。

What does that mean? First create an object that takes in your sketchy third-party object in the constructor. In it, write a slot that wraps a call to the throwing slot with a try/catch block. Now instead of connecting to the sketchy third-party object's slot, connect to your newly create object's slot.

通过这种方式捕获异常可以使相关代码保持在一起,并防止 QApplication :: notify 如果遇到多个以上有问题的功能,则不要填充一堆无关的try / catch块。

Doing the exception catching this way keeps related code together, and prevents QApplication::notify from filling up with a bunch of unrelated try/catch blocks if you encounter more than one of these problematic functions.

例如:

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的答案。使用全局处理程序来解决全局问题是很合理的。

The obvious example of this sort of global concern is an unexpected exception. Mistakes can happen anywhere. It would be desirable to log as many details about the event as possible so the cause could be identified and corrected. In this case, you would want to reimplement QApplication::notify in your own subclass as shown in jichi's answer. Using a global handler for global concerns is quite reasonable.

这篇关于如何在Qt中捕获异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆