I have a list of errors in c++ and I want to expose it to QML. Enum is registered using Q_ENUM and property is registered using Q_PROPERTY. You can see details below:
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<LoginErrorCode> loginErrors READ getLoginErrors NOTIFY loginErrorsChanged)
...
public:
...
enum LoginErrorCode {
UsernameOrPassIsNotValid
};
Q_ENUM(LoginErrorCode)
enum GetUserInfoErrorCode {
GetUserInfoError_TokenIsNotValid
};
Q_ENUM(GetUserInfoErrorCode)
QList<LoginErrorCode> getLoginErrors() const;
...
signals:
...
void loginFailed();
...
void loginErrorsChanged();
...
private:
QList<LoginErrorCode> m_loginErrors;
};
and I registered MyClass using following line in main.cpp:
qmlRegisterType<MyClass>("ir.MyComponents", 1, 0, "MyClass");
and in QML I used that class using:
MyClass {
id: myClass
Component.onCompleted: login("irani", "iravani");
onLoginFailed: console.log("Login failed with errors count: "+loginErrors.length);
}
and output is:
QMetaProperty::read: Unable to handle unregistered datatype 'QList<LoginErrorCode>' for property 'MyClass::loginErrors'
qrc:/main.qml:46: TypeError: Cannot read property 'length' of undefined
What is the problem?!
How can I expose my list of enums to qml?
For QQmlListProperty documentation says:
Note: QQmlListProperty can only be used for lists of QObject-derived object pointers.
As you can see from the documentation,
QListis supported only for a limited set of types (int,qreal, and so on). See section Sequence Type to JavaScript Array for further details.You should use
QVariantListfor your purposes instead. It is directly mapped to JavaScriptArray. See section QVariantList and QVariantMap to JavaScript Array and Object for further details.Note also the explicit mention:
Of course, you can still use a
QList<LoginErrorCode>internally, but a conversion to aQVariantListis required whenever you want to return it within the QML environment.