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 &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;
        }
    
        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 !


  • Moderators

    Hi @bnmalfrax and Welcome,
    I think UserData 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.


  • Moderators

    @bnmalfrax
    Can you try converting UserData to UserData* in Q_PROPERTY ?



  • Thanks, it work !



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.