Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Unable to handle unregistered datatype

Unable to handle unregistered datatype

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlhandleserrortypesingleton
5 Posts 2 Posters 9.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • bnmalfraxB Offline
    bnmalfraxB Offline
    bnmalfrax
    wrote on last edited by bnmalfrax
    #1

    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 !

    p3c0P 1 Reply Last reply
    0
    • bnmalfraxB bnmalfrax

      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 !

      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      Hi @bnmalfrax and Welcome,
      I think UserData needs to be declared metatype. See Q_DECLARE_METATYPE.

      157

      1 Reply Last reply
      1
      • bnmalfraxB Offline
        bnmalfraxB Offline
        bnmalfrax
        wrote on last edited by
        #3

        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.

        p3c0P 1 Reply Last reply
        0
        • bnmalfraxB bnmalfrax

          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.

          p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

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

          157

          1 Reply Last reply
          0
          • bnmalfraxB Offline
            bnmalfraxB Offline
            bnmalfrax
            wrote on last edited by
            #5

            Thanks, it work !

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved