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. How do you handle multiple inherited Q_PROPERTYs?

How do you handle multiple inherited Q_PROPERTYs?

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 2.7k 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
    #1

    Lets take this example:

    class FurColorInterface {
        Q_GADGET
        Q_PROPERTY(QColor furColor READ furColor WRITE setFurColor)
    public:
        FurColorInterface(const QColor& val) :m_furColor(val) {}
        virtual ~FurColorInterface() = 0 {}
        const QColor& furColor() const { return m_furColor; }
        void setFurColor(const QColor& val) { m_furColor = val; }
    private:
        QColor m_furColor;
    };
    class AddressInterface
    {
        Q_GADGET
        Q_PROPERTY(QString homeAddress READ homeAddress WRITE setHomeAddress)
    public:
        AddressInterface(const QString& val) :m_homeAddress(val) {}
        virtual ~AddressInterface() = 0 {}
        const QString& homeAddress() const { return m_homeAddress; }
        void setHomeAddress(const QString& val) { m_homeAddress = val; }
    private:
        QString m_homeAddress;
    };
    
    class HumanObject : public QObject, public AddressInterface
    {/*stuff*/};
    class DogObject : public QObject, public FurColorInterface, public AddressInterface
    {/*stuff*/};
    class BearObject : public QObject, public FurColorInterface
    {/*stuff*/};
    

    Of course the properties will not be inherited because only the first class inherited will ever be considered by the meta-object system, on the other hand I would like to maintain the interfaces completely separately from any concrete class inheriting from them.
    Did you ever come across this problem?
    How did you work around it?

    My guess is that ultimately I would have to remove the Q_GADGET macro altogether and move the Q_PROPERTY declaration in the concrete classes duplicating the code but I wanted to check if there was another way

    "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

    kshegunovK 1 Reply Last reply
    0
    • VRoninV VRonin

      Lets take this example:

      class FurColorInterface {
          Q_GADGET
          Q_PROPERTY(QColor furColor READ furColor WRITE setFurColor)
      public:
          FurColorInterface(const QColor& val) :m_furColor(val) {}
          virtual ~FurColorInterface() = 0 {}
          const QColor& furColor() const { return m_furColor; }
          void setFurColor(const QColor& val) { m_furColor = val; }
      private:
          QColor m_furColor;
      };
      class AddressInterface
      {
          Q_GADGET
          Q_PROPERTY(QString homeAddress READ homeAddress WRITE setHomeAddress)
      public:
          AddressInterface(const QString& val) :m_homeAddress(val) {}
          virtual ~AddressInterface() = 0 {}
          const QString& homeAddress() const { return m_homeAddress; }
          void setHomeAddress(const QString& val) { m_homeAddress = val; }
      private:
          QString m_homeAddress;
      };
      
      class HumanObject : public QObject, public AddressInterface
      {/*stuff*/};
      class DogObject : public QObject, public FurColorInterface, public AddressInterface
      {/*stuff*/};
      class BearObject : public QObject, public FurColorInterface
      {/*stuff*/};
      

      Of course the properties will not be inherited because only the first class inherited will ever be considered by the meta-object system, on the other hand I would like to maintain the interfaces completely separately from any concrete class inheriting from them.
      Did you ever come across this problem?
      How did you work around it?

      My guess is that ultimately I would have to remove the Q_GADGET macro altogether and move the Q_PROPERTY declaration in the concrete classes duplicating the code but I wanted to check if there was another way

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      Fixing a bit your example so it compiles, you can do this:

      HumanObject object; // Sets something for the property in the constructor
      int index = AddressInterface::staticMetaObject.indexOfProperty("homeAddress");
      QMetaProperty property = AddressInterface::staticMetaObject.property(index);
      
      qDebug() << property.readOnGadget(qobject_cast<AddressInterface *>(&object)).toString();
      

      albeit a cumbersome approach I admit ...

      Read and abide by the Qt Code of Conduct

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

        Thanks, I forgot to mention my final aim is to expose the properties to QML and that languae is not that smart. Btw nice to know it's possible at least in C++

        "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

        kshegunovK 1 Reply Last reply
        0
        • VRoninV VRonin

          Thanks, I forgot to mention my final aim is to expose the properties to QML and that languae is not that smart. Btw nice to know it's possible at least in C++

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by kshegunov
          #4

          Well, Luca, I'm no QML expert, but I'm pretty sure you're out of luck ... I don't think this construct can be exposed to QML. None of the relevant methods: QObject::property, QObject::setProperty or QObject::dynamicPropertyNames() is virtual, so I don't see how it can be done. You could in principle just duplicate the Q_PROPERTY macro in the deriving classes, which will work, but then that defeats the whole purpose of having the macro in the interfaces, doesn't it?

          PS.
          Probably using some of the smart copy-paste machinery we call "templates" could shorten the code and/or setting the properties manually in the QObject constructor based on the inherited interfaces' staticMetaObject instances could work ...

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            I did forgot to mention that, but did you check the bugtracker, there might be something on this moc deficiency, and if it doesn't I think filing it as a feature request is certainly warranted.

            Read and abide by the Qt Code of Conduct

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

              when you add Q_INVOKABLE methods is even worse, i ended up having to declare them pure virtual (but with the implementation) and in the concrete define them as Q_INVOKABLE and calling the base implementation. not ideal but I also think it's not something that moc can easily manage in the near future

              "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

              kshegunovK 1 Reply Last reply
              0
              • O Offline
                O Offline
                Oleksandr Malyushytskyy
                wrote on last edited by
                #7

                My impression is that the main problem is that to use of Q_PROPERTY requires the class be already derived from QObject.
                So you can't use it in interface and later derive from it and QObject.

                VRoninV 1 Reply Last reply
                0
                • O Oleksandr Malyushytskyy

                  My impression is that the main problem is that to use of Q_PROPERTY requires the class be already derived from QObject.
                  So you can't use it in interface and later derive from it and QObject.

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  @Oleksandr-Malyushytskyy said in How do you handle multiple inherited Q_PROPERTYs?:

                  My impression is that the main problem is that to use of Q_PROPERTY requires the class be already derived from QObject

                  No, you can still use it in non-QObjects using the Q_GADGET macro

                  "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
                  1
                  • VRoninV VRonin

                    when you add Q_INVOKABLE methods is even worse, i ended up having to declare them pure virtual (but with the implementation) and in the concrete define them as Q_INVOKABLE and calling the base implementation. not ideal but I also think it's not something that moc can easily manage in the near future

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #9

                    @VRonin said in How do you handle multiple inherited Q_PROPERTYs?:

                    not ideal but I also think it's not something that moc can easily manage in the near future

                    Perhaps not, but in my opinion should, even if it's in the distant future. ;)

                    Read and abide by the Qt Code of Conduct

                    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