Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Nesting JSON structure with Q_PROPERTY from a QObject



  • I have a working solutions which will convert properties to JSON format. This works for all my subclasses to JSONBase. JSONBase does two things converts to JSON and from JSON by parsing throught the meta layer and reteriving the properties of the subclass and then putting them into a QJsonValue.

    The Problem I am running into is when my Q_PROPERTY( ) type is another type. in the case below a simple struct. When the TOJSON function tries to convert the QVariant to QJsonValue when the varaint contains my customs struct. The return value is null. So I tried to come up with another way to parse the QVariant and abstract the properties from the struct and create a nested QJSONValue but have had no luck. Please see below as I try to explain what I am doing. In code below for how I convert to JSON. I have added comments for where I am trying to determine how to solve my problem .

    JSON structure I am trying to achieve

    {
        "className":"classA"
        "propertyInt":1
        "propertyQString":"Hello"
        "propertyStrucA":
         {
             "x":1
             "y":2
         }
    }
    

    ClassA

    class ClassA: public QObject
    {
        Q_OBJECT
        Q_PROPERTY(int propertyInt, READ propertyInt, WRITE setpropertyInt NOTIFY propertyIntChanged)
        Q_PROPERTY(QString propertyQString, READ propertyQString, WRITE setpropertyQString NOTIFY propertyQStringChanged)
        Q_PROPERTY(_StrucA propertyStrucA, READ propertyStrucA, WRITE setpropertyStrucAt NOTIFY propertyStrucAChanged)
    ...
    

    Struct A

    typdef struct _StrucA
    {
      Q_GADGET
      Q_PROPERTY(int x MEMEBER x)
      Q_PROPERTY(int y MEMEBER y)
    ...
    }StrucA;
    Q_DECLARE_METATYPE(_StrucA)
    

    Heres How I am Converting To JSON

     try {
            err = DATAMODELERRORCODES::NO_ERROR;
            QJsonObject dmJSON;
            // we use the metaobject to get the name of each property defined by Q_PROPERTY
            for(int i =0; i < this->metaObject()->propertyCount(); i++)
            {
    
                QMetaProperty metaProperty = this->metaObject()->property(i);
                const char* propertyName = metaProperty.name();
                const QVariant& propertyValue =  this->property(propertyName);
                QJsonValue propertyValueJSON;
    
                if(metaProperty.isEnumType())
                {
                   propertyValueJSON = this->property(propertyName).toInt();
                }
                else
                {
                  propertyValueJSON = QJsonValue::fromVariant(propertyValue);
                  if(propertyValueJSON == QJsonValue::Null)
                  {
                      //Here I failed to convert Struct A into a QJsonValue
                      // So how do I convert the QVariant propertyValue back to StuctA
                      // I cant due auto value = propertyValue<StructA>.value() becuase this is
                     // a generic class meaning I use this code to convert a series of object to json 
                    // so is there a way to convert the QVariant to structA or at least read the data of the QVariant without covering
                   // when I put a break point in my code I can see that propertyValue has a member named data which contains the properties of Struct A. which these values I would like to insert into the JSON structure
                  }
                }
    
                dmJSON.insert(propertyName,propertyValueJSON);
            }
            // 3. return data model as a json object
            return  dmJSON;
        } catch (std::exception & e) {
            qWarning() << "Error Occurred converting %s to JSON. Error: %s",this->metaObject()->className(),e.what();
            err = DATAMODELERRORCODES::FAILDED_TO_COVERT_TO_JSON;
            QJsonObject emptyJSON;
            return emptyJSON;
        }
    

    any help would be greatly appericated


Log in to reply