Qt:从 C++ 向 QML 引擎抛出异常
Posted
技术标签:
【中文标题】Qt:从 C++ 向 QML 引擎抛出异常【英文标题】:Qt: Throwing an exception from C++ to QML engine 【发布时间】:2016-12-30 18:03:45 【问题描述】:当从QML
中的javascript
函数调用C++
中编写的Q_INVOKABLE
方法时,如何抛出异常?该方法由 < MyApp >
类型的对象拥有,并通过调用 qmlRegisterType()
注册
例如,我有以下 QML 代码:
TextField
id: fld_recipient
onEditingFinished:
try
var identity=myapp.identities.current_Identity;
var company=identity.companies.current_Company;
myapp.lookup_email(identity.identity_id,company.company_id,fld_recipient.text)
catch(e)
console.log(e);
这里,方法 MyApp::lookup_email() 进入服务器并搜索匹配的电子邮件地址。这个过程可能会因大量错误而停止,我希望 catch() 语句显示该错误。
这是如何在 C++ 端完成的?有点像这样:
void MyApp::lookup_email(int identity_id,int company_id,QString email)
....
error_code=server->lookup_email(identity_id,company_id,email);
if (error_code) /// throw an exception to QML engine,
????? <= what goes here ?
【问题讨论】:
如果发生错误则返回一个空字符串,并在QML中检查该字符串是否真的包含电子邮件。 还有这个lists.qt-project.org/pipermail/interest/2015-April/016652.html 老实说,我不会费心处理异常,只需使用经典的返回码。这甚至与技术无关,但就我而言,我无法想象自己在一年前考虑某个项目 - 哦该死的......这个异常来自哪里以及它在哪里处理=) @evilruff,我想让它对将要使用我的组件的 JavaScript 开发人员更友好。 Q_INVOKABLE C++ 方法依赖于其他变量,例如,如果它们为 NULL,我想抛出一个 TypeError 说某个变量是“未定义” 你有没有得到这个答案?我试图做同样的事情...... 【参考方案1】:Qml 不应包含任何业务逻辑,而应仅显示任何结果。如果您的应用程序遇到异常状态,请在业务逻辑中捕获异常并将结果/新状态呈现给用户。
如果您假设您的 (UI) 代码将使用不完整的数据调用,您应该忽略它。或者在调试级别使用断言。
【讨论】:
【参考方案2】:以下代码 sn-p 显示了您可以如何使用QQmlEngine::throwError
:
#ifndef __MathTools__
#define __MathTools__
#include <QObject>
#include <QQmlEngine>
#include <QString>
class MathTools : public QObject
Q_OBJECT
public:
MathTools(QObject* parent = nullptr) : QObject(parent)
Q_INVOKABLE double divide(double a, double b)
if (b == 0.0)
qmlEngine(this)->throwError(tr("Division by zero error"));
return 0.0;
return a / b;
;
#endif
在 QML 中使用时:
Flickable
id: flickable
anchors.fill: parent
anchors.margins: 10
contentWidth: columnLayout.width
contentHeight: columnLayout.height
clip: true
ColumnLayout
id: columnLayout
width: flickable.width
TextEdit
id: firstTextEdit
Layout.fillWidth: true
font.pointSize: styles.textPointSize
selectByMouse: true
TextEdit
id: secondTextEdit
Layout.fillWidth: true
font.pointSize: styles.textPointSize
selectByMouse: true
Button
text: qsTr("Divide")
font.pointSize: styles.textPointSize
onClicked:
resultTextEdit.text = "";
const first = parseFloat(firstTextEdit.text);
const second = parseFloat(secondTextEdit.text);
const result = mathTools.divide(first, second);
resultTextEdit.text = result;
Text
id: resultTextEdit
Layout.fillWidth: true
font.pointSize: styles.textPointSize
我看到尝试除以零时抛出 QML/Javascript 错误:
qrc:/main.qml:58: Error: Division by zero error
参考:
https://doc.qt.io/qt-5/qjsengine.html#throwError【讨论】:
在我的 QQuickItem 子类中这样尝试过:QQmlEngine::contextForObject(this)->engine()->throwError(QJSValue::SyntaxError, "Custom Error Message");
不做任何事情。我错过了什么?
@mchiasson 从文档来看,它看起来不像 C++ 抛出,它只会在控件返回 JS 引擎时触发 JS 异常。换句话说,在最顶层的函数中使用它。
@mchiasson 我已更新我的答案以显示qmlEngine(this)->throwError(...)
以上是关于Qt:从 C++ 向 QML 引擎抛出异常的主要内容,如果未能解决你的问题,请参考以下文章