How do you handle multiple inherited Q_PROPERTYs?



  • 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


  • Qt Champions 2016

    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 ...



  • 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++


  • Qt Champions 2016

    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 ...


  • Qt Champions 2016

    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.



  • 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



  • 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.



  • @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


  • Qt Champions 2016

    @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. ;)


Log in to reply
 

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