Reputation: 7360
When calling a Q_INVOKABLE
method written in C++
from a JavaScript
function in QML
, how do you throw an exception ? The method is owned by an object of a type < MyApp >
, registered with a call qmlRegisterType()
For example, I have the following QML code:
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);
}
}
}
Here, the method MyApp::lookup_email() goes to the server and searches for matching email addresses. This process can be stopped by a large amount of errors and I want the catch() statement to show that error.
How is this done on the C++ side ? Kind of like this:
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 ?
}
}
Upvotes: 8
Views: 2830
Reputation: 25891
The following code snippet shows how you may use 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
When used in QML:
ColumnLayout {
TextField { id: first; text: "1" }
TextField { id: second; text: "0" }
Button {
text: qsTr("Divide")
onClicked: {
try {
const f = parseFloat(first.text);
const s = parseFloat(second.text);
result.text = mathTools.divide(f, s);
} catch (err) {
result.text = err.message;
}
}
}
TextField { id: result }
}```
I see a QML/Javascript error being thrown when attempting to divide by zero:
qrc:/main.qml:58: Error: Division by zero error
Reference:
- https://doc.qt.io/qt-5/qjsengine.html#throwError
Upvotes: 3
Reputation: 2825
Qml should not include any business logic but just display any results. In case your application runs into an exception state catch the exception in the business logic and present the resulting/new state to the user.
In case you assume your (UI) code will be called with incomplete data you should just ignore it. Or use assertions on debug level.
Upvotes: 3