Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QObject::setProperty and custom class
Forum Updated to NodeBB v4.3 + New Features

QObject::setProperty and custom class

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 4.5k Views 2 Watching
  • 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #2

    link is an object, as documented here it will be converted to a QVariantMap, having href and rel as keys. There is no way for the QJasonValue::toVariant() to know that your object is a Link so it cannot possibly convert it to it.

    if you provide:

    Link::Link(const QVariantMap& val){
    m_sHref = val.value("href").toString();
    m_sRel = val.value("rel").toString();
    }
    Link& Link::operator=(const QVariantMap& val){
    m_sHref = val.value("href").toString();
    m_sRel = val.value("rel").toString();
    return *this;
    }
    

    it might work

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    1 Reply Last reply
    0
    • P Offline
      P Offline
      Pswin
      wrote on last edited by
      #3

      Actually, I have provided, but It did not work

      Link ( const QVariantMap& _map )
          {
              m_sHref = _map["href"].toString();
              m_sRel = _map["rel"].toString();
          }
      
         Link& operator= ( const QVariantMap& _map )
          {
              m_sHref = _map["href"].toString();
              m_sRel = _map["rel"].toString();
              qDebug() << "called" ;
              return *this;
          }
      
      1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #4

        could you qDebug() << obj[var].type() << " - " << obj[var].toVariant().type(); and tell us what it prints?

        I'm afraid you'll have to do it manually btw

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        0
        • P Offline
          P Offline
          Pswin
          wrote on last edited by
          #5

          I have added following code to 'EnterpriseEntity::fromJson' method (in the loop):

          qDebug() << this->metaObject()->className() << var << obj[var].toVariant();
          qDebug() << obj[var].type() << " - " << obj[var].toVariant().type();
          

          and output is like that:

          User "link" QVariant(QVariantMap, QMap(("href", QVariant(QString, "http://localhost/api/users/Ema"))("rel", QVariant(QString, "self"))))
          5  -  QVariant::QVariantMap
          
          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #6

            Then I'm afraid it's manual:

            const auto allKeys = obj.keys();
             for ( const QString& var : allKeys   ) //this is more efficient
                    {
            if(obj[var].type()==QJsonValue::Object){
            
                            if ( !setProperty( var.toLatin1().constData(), obj[var].type()==QJsonValue::Object ? QVariant(Link(obj[var].toVariant())):  obj[var].toVariant() ) )
                            {
                                qDebug() << "Error in seting: " << var;
                            }
                    }
            

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            0
            • P Offline
              P Offline
              Pswin
              wrote on last edited by
              #7

              @VRonin said in QObject::setProperty and custom class:

              Then I'm afraid it's manual:

              I hope not. It would be the worst option. In particular for big and enterprise software.

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #8

                ok, last try (as I think I'm getting drunk on all these nested types)

                Link::Link(const QVariant& vart){
                if(vart.type()==QMetaType::QVariantMap){
                const QVariantMap val= vart.toVariantMap();
                m_sHref = val.value("href").toString();
                m_sRel = val.value("rel").toString();
                }
                }
                Link& Link::operator=(const QVariant& vart){
                if(vart.type()==QMetaType::QVariantMap){
                const QVariantMap val= vart.toVariantMap();
                m_sHref = val.value("href").toString();
                m_sRel = val.value("rel").toString();
                }
                return *this;
                }
                

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  Pswin
                  wrote on last edited by
                  #9

                  @VRonin said in QObject::setProperty and custom class:

                  ok, last try (as I think I'm getting drunk on all these nested types)

                  I had done that too :(.

                  Telling the truth, me too. however Qt is great library, it doesn't support some basic and essential classes ( and I haven't any idea why?! ).For instance, there is not any class for working with integers that could accept null values, while there are database adapters and support in it ( and it goes without saying that nullable fields are a vital part of any database design.)

                  I was about writing these classes by myself (such as Integer, etc.), nevertheless I faced to this problem.

                  this is a complete version of my Link class:

                  class Link
                  {
                  public:
                  
                      explicit Link ( );
                  
                      Link ( const Link& _link );
                  
                      Link ( const QVariant& _var );
                  
                      Link ( const QVariantMap& _map );
                  
                      operator QVariant() const;
                  
                  
                     bool operator != ( const Link& _left );
                  
                     Link& operator= ( const QVariantMap& _map );
                  
                     Link& operator= ( const QVariant& _var );
                  
                     QString getHref( void ) const { return m_sHref; }
                  
                     void setHref( const QString& _link ) { m_sHref = _link; }
                  
                     QString getRelation( void) const { return m_sRel; }
                  
                     void setRelation( const QString& _rel ) { m_sRel = _rel; }
                  
                  private:
                      QString m_sHref;
                      QString m_sRel;
                  };
                  
                  VRoninV kshegunovK 2 Replies Last reply
                  0
                  • P Pswin

                    @VRonin said in QObject::setProperty and custom class:

                    ok, last try (as I think I'm getting drunk on all these nested types)

                    I had done that too :(.

                    Telling the truth, me too. however Qt is great library, it doesn't support some basic and essential classes ( and I haven't any idea why?! ).For instance, there is not any class for working with integers that could accept null values, while there are database adapters and support in it ( and it goes without saying that nullable fields are a vital part of any database design.)

                    I was about writing these classes by myself (such as Integer, etc.), nevertheless I faced to this problem.

                    this is a complete version of my Link class:

                    class Link
                    {
                    public:
                    
                        explicit Link ( );
                    
                        Link ( const Link& _link );
                    
                        Link ( const QVariant& _var );
                    
                        Link ( const QVariantMap& _map );
                    
                        operator QVariant() const;
                    
                    
                       bool operator != ( const Link& _left );
                    
                       Link& operator= ( const QVariantMap& _map );
                    
                       Link& operator= ( const QVariant& _var );
                    
                       QString getHref( void ) const { return m_sHref; }
                    
                       void setHref( const QString& _link ) { m_sHref = _link; }
                    
                       QString getRelation( void) const { return m_sRel; }
                    
                       void setRelation( const QString& _rel ) { m_sRel = _rel; }
                    
                    private:
                        QString m_sHref;
                        QString m_sRel;
                    };
                    
                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #10

                    could you try to implement an explicit reader and writer for the function? it might be that in that case implicit conversion is executed (so keep that QVariant constructor):

                    It is manual :(

                    @Pswin said in QObject::setProperty and custom class:

                    it doesn't support some basic and essential classes

                    Let's be honest, this is far from essential, you are just trying to find a lazy solution that saves you checking what var contains. an if on it solves your problem straight away

                    P.S.
                    @Pswin said in QObject::setProperty and custom class:

                    integers that could accept null values

                    That's actually very easy to implement using pointers (or smart pointers):

                    std::unique_ptr<int> nullableInt; //start with a null int
                    
                    if(nullableInt)
                    qDebug() << "int is valid, value: " << *nullableInt;
                    else
                    qDebug("int is null");
                    
                    nullableInt = std::make_unique<int>(3); // set it to 3
                    
                    if(nullableInt)
                    qDebug() << "int is valid, value: " << *nullableInt;
                    else
                    qDebug("int is null");
                    
                    nullableInt.reset(); //set it back to null
                    
                    if(nullableInt)
                    qDebug() << "int is valid, value: " << *nullableInt;
                    else
                    qDebug("int is null");
                    

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    P 1 Reply Last reply
                    1
                    • VRoninV VRonin

                      could you try to implement an explicit reader and writer for the function? it might be that in that case implicit conversion is executed (so keep that QVariant constructor):

                      It is manual :(

                      @Pswin said in QObject::setProperty and custom class:

                      it doesn't support some basic and essential classes

                      Let's be honest, this is far from essential, you are just trying to find a lazy solution that saves you checking what var contains. an if on it solves your problem straight away

                      P.S.
                      @Pswin said in QObject::setProperty and custom class:

                      integers that could accept null values

                      That's actually very easy to implement using pointers (or smart pointers):

                      std::unique_ptr<int> nullableInt; //start with a null int
                      
                      if(nullableInt)
                      qDebug() << "int is valid, value: " << *nullableInt;
                      else
                      qDebug("int is null");
                      
                      nullableInt = std::make_unique<int>(3); // set it to 3
                      
                      if(nullableInt)
                      qDebug() << "int is valid, value: " << *nullableInt;
                      else
                      qDebug("int is null");
                      
                      nullableInt.reset(); //set it back to null
                      
                      if(nullableInt)
                      qDebug() << "int is valid, value: " << *nullableInt;
                      else
                      qDebug("int is null");
                      
                      P Offline
                      P Offline
                      Pswin
                      wrote on last edited by
                      #11

                      @VRonin

                      Using 'Boost.Optional' would be better option:

                      http://www.boost.org/doc/libs/1_47_0/libs/optional/doc/html/index.html

                      like:

                      boost::optional<int> m_iID;
                      

                      Honestly, As I am developing a large scale application, I am looking for ways that are not error prone. Checking members manually again and again in every class makes software more liable for bugs and harder to control and revise. As result, such class are essential to me (at least).

                      1 Reply Last reply
                      0
                      • P Pswin

                        @VRonin said in QObject::setProperty and custom class:

                        ok, last try (as I think I'm getting drunk on all these nested types)

                        I had done that too :(.

                        Telling the truth, me too. however Qt is great library, it doesn't support some basic and essential classes ( and I haven't any idea why?! ).For instance, there is not any class for working with integers that could accept null values, while there are database adapters and support in it ( and it goes without saying that nullable fields are a vital part of any database design.)

                        I was about writing these classes by myself (such as Integer, etc.), nevertheless I faced to this problem.

                        this is a complete version of my Link class:

                        class Link
                        {
                        public:
                        
                            explicit Link ( );
                        
                            Link ( const Link& _link );
                        
                            Link ( const QVariant& _var );
                        
                            Link ( const QVariantMap& _map );
                        
                            operator QVariant() const;
                        
                        
                           bool operator != ( const Link& _left );
                        
                           Link& operator= ( const QVariantMap& _map );
                        
                           Link& operator= ( const QVariant& _var );
                        
                           QString getHref( void ) const { return m_sHref; }
                        
                           void setHref( const QString& _link ) { m_sHref = _link; }
                        
                           QString getRelation( void) const { return m_sRel; }
                        
                           void setRelation( const QString& _rel ) { m_sRel = _rel; }
                        
                        private:
                            QString m_sHref;
                            QString m_sRel;
                        };
                        
                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by kshegunov
                        #12

                        @Pswin said in QObject::setProperty and custom class:

                        For instance, there is not any class for working with integers that could accept null values

                        This makes no sense at all. There's no null semantics put into integers, that's a db thing and C++ has no notion of it. As such the ambiguity is wrapped in QVariant (which wraps around a union) as it should. QVariant::isNull is probably what you're expecting to find.

                        @VRonin said in QObject::setProperty and custom class:

                        That's actually very easy to implement using pointers (or smart pointers)

                        Oh, come on Luca, are we going to start creating individual characters in the heap next?
                        Here's how it could be done the right way (which QVariant already does internally):

                        struct SpecialValue
                        {
                            enum SupportedTypes { NullType, IntType, DoubleType };
                        
                            SupportedTypes type;  // Contains the type currently set (the active field in the union)
                            union  {
                                int intValue;
                                double doubleValue;
                            } data;  // The data
                        };
                        

                        @Pswin

                        What you probably want to implement is an interface that will abstract the streaming from and to a JsonObject and all objects that implement that would call each of their properties that implement it to serialize themselves. Then the other way around is exactly the same. E.g. (I leave the serialization to your imagination):

                        class JsonSerializable
                        {
                        public:
                            virtual QJsonObject toJsonObject() const = 0;
                            virtual void fromJsonObject(const QJsonObject &) = 0;
                        };
                        
                        class EnterpriseEntity : public QObject, public JsonSerializable
                        {
                            // ...
                            void fromJsonObject(const QJsonObject & object) override
                            {
                                // Other properties
                                // ...
                                // Link
                                Link link;
                                link.fromJsonObject(object.value("link").toObject());
                                setProperty("link", link);
                            }
                        }
                        
                        class Link : public JsonSerializable
                        {
                        public:
                            void fromJsonObject(const QJsonObject & object) override
                            {
                                m_sHref = object.value("href").toString();
                                m_sRel = object.value("rel").toString();
                            }
                        };
                        

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        2

                        • Login

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