Unsolved 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
-
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++
-
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
orQObject::dynamicPropertyNames()
is virtual, so I don't see how it can be done. You could in principle just duplicate theQ_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 theQObject
constructor based on the inherited interfaces'staticMetaObject
instances could work ... -
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 -
@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. ;)