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 ?
}
}
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.
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:
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
}
}
}
I see a QML/Javascript error being thrown when attempting to divide by zero:
qrc:/main.qml:58: Error: Division by zero error
Reference:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With