c++qtinheritanceqproperty

Accessing Q_Properties of a class inherited from an Object that inherited from QObject


I have the following simplified setup where I'm trying to access the Q_Properties on the inherited class of a class that inherits from QObject. I can access the properties of the base class just fine but I can't find or see (while debugging) the properties of my inherited class:

Base Class:

class Vehicle : public QObject
{
   Q_OBJECT
   Q_PROPERTY(QString model READ getModel WRITE setModel)      
public:
   explicit Vehicle(QObject *parent = 0);
   QString getModel() const;      
   void setModel(QString model);
   virtual QString toString() const;
private:
    QString _model;
};

Inherited Class:

class TransportVehicle : public Vehicle
{
    Q_PROPERTY(int Capacity READ getCapacity WRITE setCapacity)

public:
    TransportVehicle();
    TransportVehicle(int, QString, int);
    int getCapacity() const;
    void setCapacity(int);

    QString toString() const;
private:
    int _maxCapacity;
};

and the following snippet from a generic method to access the properties of which ever object it finds in the list that is passed to it:

int write(QObjectList* list) {
int count = 0;
for(int i = 0; i < list->size(); i++)
{
    const QMetaObject *mo = list->at(i)->metaObject();
    for(int k = mo->propertyOffset(); k < mo->propertyCount(); k++)
    {
        const QMetaProperty prop = mo->property(k);
        QString name = prop.name();
        QString valStr = prop.read(list->at(i)).toString();
        QDebug << name << ": " << valStr << endl; 
        count++;
    }
    delete mo;
}
return count;
}

It works fine except my output will be like 'model: toyota' and won't include capacity.

The only way I've been able to get the properties of my subclasses is to add virtual get and set methods and an additional Q_property to my base class, which doesn't seem right at all and not possible in normal circumstances where I don't have access to the base class.


Solution

  • Vehicle inherits QObject, so TransportVehicle will have to use the Q_OBJECT macro, Q_GADGET is when you don't inherit QObject and want a meta object.

    Every class which directly on indirectly inherits QObject needs the Q_OBJECT macro. You don't have it in TransportVehicle so you don't get meta data generated for it, you are stuck with the meta object that was generated for the base class.