Unable to handle unregistered datatype
-
Hello !
I have the error Unable to handle unregistered datatype when I want to use my custom QObject UserData from a singleton.
If I declare the UserData in a qml file, it work.Here my code :
UserData.h#ifndef USERDATA_H #define USERDATA_H #include <QImage> #include <QObject> #include <QDate> class UserData : public QObject { Q_OBJECT Q_PROPERTY(QString firstName READ firstName WRITE setFirstName NOTIFY firstNameChanged) Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged) Q_PROPERTY(QString lastName READ lastName WRITE setLastName NOTIFY lastNameChanged) Q_PROPERTY(QDate birthday READ birthday WRITE setBirthday NOTIFY birthdayChanged) Q_PROPERTY(QString twitter READ twitter WRITE setTwitter NOTIFY twitterChanged) Q_PROPERTY(QString linkedin READ linkedin WRITE setLinkedin NOTIFY linkedinChanged) Q_PROPERTY(QString viadeo READ viadeo WRITE setViadeo NOTIFY viadeoChanged) public: UserData(); UserData(const UserData ©) { m_firstName = copy.m_firstName; m_lastName = copy.m_lastName; m_id = copy.m_id; m_birthday = copy.m_birthday; m_twitter = copy.m_twitter; m_linkedin = copy.m_linkedin; m_viadeo = copy.m_viadeo; } UserData &operator=(const UserData& copy) { m_firstName = copy.m_firstName; m_lastName = copy.m_lastName; m_id = copy.m_id; m_birthday = copy.m_birthday; m_twitter = copy.m_twitter; m_linkedin = copy.m_linkedin; m_viadeo = copy.m_viadeo; return *this; } UserData(int id, QString firstName, QString lastName); QString firstName() const { return m_firstName; } int id() const { return m_id; } QString lastName() const { return m_lastName; } QDate birthday() const { return m_birthday; } QString twitter() const { return m_twitter; } QString linkedin() const { return m_linkedin; } QString viadeo() const { return m_viadeo; } signals: void firstNameChanged(QString firstName); void idChanged(int id); void lastNameChanged(QString lastName); void birthdayChanged(QDate birthday); void twitterChanged(QString twitter); void linkedinChanged(QString linkedin); void viadeoChanged(QString viadeo); public slots: void setFirstName(QString firstName) { if (m_firstName == firstName) return; m_firstName = firstName; emit firstNameChanged(firstName); } void setId(int id) { if (m_id == id) return; m_id = id; emit idChanged(id); } void setLastName(QString lastName) { if (m_lastName == lastName) return; m_lastName = lastName; emit lastNameChanged(lastName); } void setBirthday(QDate birthday) { if (m_birthday == birthday) return; m_birthday = birthday; emit birthdayChanged(birthday); } void setTwitter(QString twitter) { if (m_twitter == twitter) return; m_twitter = twitter; emit twitterChanged(twitter); } void setLinkedin(QString linkedin) { if (m_linkedin == linkedin) return; m_linkedin = linkedin; emit linkedinChanged(linkedin); } void setViadeo(QString viadeo) { if (m_viadeo == viadeo) return; m_viadeo = viadeo; emit viadeoChanged(viadeo); } private: QString m_firstName; int m_id; QString m_lastName; QDate m_birthday; QString m_twitter; QString m_linkedin; QString m_viadeo; }; #endif // USERDATA_H
Singleton SDataManager.h
#ifndef SDATAMANAGER_H #define SDATAMANAGER_H #include <QString> #include <QImage> #include <QJsonDocument> #include <QJsonArray> #include <QJsonObject> #include <QVariant> #include <QMap> #include <QStringList> #include <QFile> #include <QJSEngine> #include <QQmlEngine> #include "UserData.h" #include "ProjectData.h" #include "SDebugLog.h" #include "IDataConnector.h" #define USER_TOKEN API::SDataManager::GetDataManager()->GetToken() #define PROJECT API::SDataManager::GetDataManager()->GetCurrentProject() #define GENERATE_JSON_DEBUG API::SDataManager::GenerateFileDebug(__data) #define SHOW_JSON(param) API::SDataManager::GenerateFileDebug(param) #define JSON_TO_DATE(date) QDateTime::fromString(date, "yyyy-MM-dd HH:mm:ss.zzzz") namespace API { class SDataManager : public QObject { Q_OBJECT Q_PROPERTY(UserData user READ user WRITE setUser NOTIFY userChanged) Q_PROPERTY(ProjectData project READ project WRITE setProject NOTIFY projectChanged) Q_PROPERTY(QVariantList projectList READ projectList WRITE setProjectList NOTIFY projectListChanged) public: static IDataConnector *GetCurrentDataConnector(); static SDataManager *GetDataManager(); void RegisterUserConnected(int id, QString userName, QString userLastName, QString token, QImage *avatar); void LogoutUser(); static void Destroy(); static QJsonObject ParseMapDebug(QMap<QString, QVariant> &data); static void GenerateFileDebug(QMap<QString, QVariant> &data); static void GenerateFileDebug(QByteArray arr); int GetUserId() const; QString GetUserName() const; QString GetUserLastName() const; QString GetToken() const; int GetCurrentProject() const; QImage *GetAvatar(); void SetCurrentProjectId(int id); UserData user() const { return m_user; } ProjectData project() const { return m_project; } QVariantList projectList() const { return m_projectList; } public slots: void setUser(UserData user) { m_user = user; emit userChanged(user); } void setProject(ProjectData project) { m_project = project; emit projectChanged(project); } void setProjectList(QVariantList projectList) { if (m_projectList == projectList) return; m_projectList = projectList; emit projectListChanged(projectList); } signals: void userChanged(UserData user); void projectChanged(ProjectData project); void projectListChanged(QVariantList projectList); private: SDataManager(); ~SDataManager(); IDataConnector *_OfflineDataConnector; IDataConnector *_OnlineDataConnector; int _UserId; QString _UserName; QString _UserLastName; QString _Token; QImage *_Avatar; int _CurrentProject; UserData m_user; ProjectData m_project; QVariantList m_projectList; }; } #endif // SDATAMANAGER_H
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QtQml> #include "CloudController.h" #include "SDebugLog.h" #include "LoginController.h" #include "GanttView.h" #include "TaskData.h" #include "UserData.h" #include "ProjectData.h" #include "GanttModel.h" #include "API/SDataManager.h" #define GRAPPBOX_URL "GrappBoxController" #define MAJOR_VERSION 1 #define MINOR_VERSION 0 static QObject *qobject_datamanager_provider(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) return API::SDataManager::GetDataManager(); } int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); LOG(QString("Initialized !")); qmlRegisterType<CloudController>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "CloudController"); qmlRegisterType<FileData>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "FileData"); qmlRegisterType<FileDataTransit>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "FileDataTransit"); qmlRegisterType<LoginController>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "LoginController"); qmlRegisterType<GanttView>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "GanttView"); qmlRegisterType<TaskData>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "TaskData"); qmlRegisterType<UserData>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "UserData"); qmlRegisterType<TaskTagData>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "TaskTagData"); qmlRegisterType<DependenciesData>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "DependenciesData"); qmlRegisterType<GanttModel>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "GanttModel"); qmlRegisterType<ProjectData>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "ProjectData"); qmlRegisterSingletonType<API::SDataManager>(GRAPPBOX_URL, MAJOR_VERSION, MINOR_VERSION, "SDataManager", qobject_datamanager_provider); QQmlApplicationEngine engine; engine.addImportPath("modules/"); engine.load(QUrl(QStringLiteral("qrc:/qrc/qrc/main.qml"))); int ret = app.exec(); return ret; }
my qml
Item { Component.onCompleted: { console.log(user) console.log(SDataManager.user) } UserData { id: user } }
Inside the console I have :
qml: UserData(0x3270d7b0) QMetaProperty::read: Unable to handle unregistered datatype 'UserData' for property 'API::SDataManager::user' qml: undefined
I don't understand why this doesn't work with my singleton.
Thanks for your help ! -
Hi @bnmalfrax and Welcome,
I thinkUserData
needs to be declared metatype. See Q_DECLARE_METATYPE. -
Thanks that works. My UserData is now accessible.
But when I want to get a variable in the UserData, qml say me that the variable is undefined.What I'm writing :
Component.onCompleted: { console.log(SDataManager.user) console.log(SDataManager.user.id) }
and on the console I have that :
qml: QVariant(UserData) qml: undefined
It's weird because the auto-completion is working.
-
@bnmalfrax
Can you try convertingUserData
toUserData*
in Q_PROPERTY ?