Q_INVOKABLE 方法抛出异常?
Throwing an exception from Q_INVOKABLE method?
试图了解基于 Qt/QML 的应用程序的最佳实践,其中我们有标记为 Q_INVOKABLE
的方法。如果我们从其中一种方法中抛出异常,会有什么后果?
class Class
{
...
Q_INVOKABLE void method() { throw std::logic_error(); }
};
QML 可以处理这个错误,还是我会导致程序崩溃?
Q_INVOKABLE
宏只是标记函数,以便可以使用QMetaObject::invokeMethod()
调用它。它并没有真正改变 Qt 中处理异常的方式。
为此,区分通过连接调用的槽和作为普通函数直接调用的槽非常重要。如果通过信号槽连接调用方法,则抛出异常时发生的情况是不确定的,除非您实际在槽内处理异常。即,在一个插槽中,您 必须 写入:
void Class::method() {
try {
// code that might throw logic_error
} catch (std::logic_error &err) {
}
}
您不能省略 catch()
语句。
另一方面,如果直接将方法作为函数调用,则直接抛出即可。但是,必须在调用该方法的任何地方捕获和处理它。即,您必须写:
try {
obj.method();
catch (std::logic_error &err) {
// error-handling
}
这实际上都是因为 Qt 应用程序事件循环中的错误处理没有明确定义。有关详细信息,请参阅 docs on Qt 5.9。
试图了解基于 Qt/QML 的应用程序的最佳实践,其中我们有标记为 Q_INVOKABLE
的方法。如果我们从其中一种方法中抛出异常,会有什么后果?
class Class
{
...
Q_INVOKABLE void method() { throw std::logic_error(); }
};
QML 可以处理这个错误,还是我会导致程序崩溃?
Q_INVOKABLE
宏只是标记函数,以便可以使用QMetaObject::invokeMethod()
调用它。它并没有真正改变 Qt 中处理异常的方式。
为此,区分通过连接调用的槽和作为普通函数直接调用的槽非常重要。如果通过信号槽连接调用方法,则抛出异常时发生的情况是不确定的,除非您实际在槽内处理异常。即,在一个插槽中,您 必须 写入:
void Class::method() {
try {
// code that might throw logic_error
} catch (std::logic_error &err) {
}
}
您不能省略 catch()
语句。
另一方面,如果直接将方法作为函数调用,则直接抛出即可。但是,必须在调用该方法的任何地方捕获和处理它。即,您必须写:
try {
obj.method();
catch (std::logic_error &err) {
// error-handling
}
这实际上都是因为 Qt 应用程序事件循环中的错误处理没有明确定义。有关详细信息,请参阅 docs on Qt 5.9。