sma*_*llB 17 c++ qt exception-handling exception qt5
try
{ // `count()` throws exception
connect(thread, SIGNAL(started()), engine, SLOT(count()));
}
catch(const X& e)
{}
Run Code Online (Sandbox Code Playgroud)
从Qt-5开始,我收到以下错误:
Qt捕获了一个从事件处理程序抛出的异常.Qt不支持从事件处理程序中抛出异常.您不能让任何异常通过Qt代码传播.如果那是不可能的,那么在Qt 5中你必须至少重新实现
QCoreApplication::notify()
并捕获那里的所有异常.
如果我不能像上面所示那样以传统的方式捕捉异常,那么我们应该把它们赶上哪些?
cgm*_*gmb 16
在哪里我应该抓住它?
这正是Qt不支持跨信号/插槽连接抛出异常的原因.如果你试试,你会看到这样的信息:
Qt捕获了一个从事件处理程序抛出的异常.Qt不支持从事件处理程序中抛出异常.您必须重新实现QApplication :: notify()并捕获所有异常.
正如它提到的那样,有可能将QApplication子类化并在那里捕获你的异常,但这将是一种非常烦人的处理方式.
如果可能的话,我建议重写计数,使其不会抛出.
如果你不能重写count()怎么办?
例如,如果count()是您正在使用的第三方库中的函数的一部分,该怎么办?
任何官方Qt库中都没有插槽,因此如果您使用的是带有插槽的第三方库,则可能表明它不是一个好的库.无论如何你想要使用它,我建议QApplication::notify
你改为创建适配器而不是捕获它.
那是什么意思?首先创建一个对象,在构造函数中接收粗略的第三方对象.在其中,编写一个插槽,用try/catch块包装对抛出槽的调用.现在,不要连接到粗略的第三方对象的插槽,而是连接到新创建对象的插槽.
以这种方式执行异常会将相关代码保持在一起,并且QApplication::notify
如果遇到多个这些有问题的函数,则可以防止填充大量不相关的try/catch块.
例如:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果你想处理可以从任何地方抛出的东西怎么办?
这种全球关注的明显例子是意外的例外.错误可能发生在任何地方.期望记录尽可能多的关于事件的细节,以便可以识别和纠正原因.在这种情况下,您可能希望QApplication::notify
在您自己的子类中重新实现,如jichi的答案所示.使用全局处理程序来解决全局问题非常合理.
jic*_*chi 12
如果有人需要一个示例代码来覆盖QApplication :: notify,我从这里得到一个(日语):http://www.02.246.ne.jp/~torutk/cxx/qt/QtMemo.html
#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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
17851 次 |
最近记录: |