2016-03-09 6 views
0

У меня есть следующая упрощенная настройка, где я пытаюсь получить доступ к Q_Properties в классе унаследованного класса класса, который наследуется от QObject. Я могу получить доступ к свойствам базового класса просто отлично, но я не могу найти или увидеть (при отладке) свойства моего унаследованного класса:Доступ к Q_Properties класса, унаследованного от объекта, унаследованного от QObject

Базовый класс:

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; 
}; 

Наследуется Класс:

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; 
}; 

и следующий фрагмент из общего метода для доступа к свойствам которого когда-либо объект, находит в списке, который передается ему:

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; 
} 

Он отлично работает, но мой выход будет похож на «модель: toyota» и не будет включать в себя емкость.

Единственный способ получить свойства моих подклассов - добавить виртуальный метод get и set и дополнительный Q_property к базовому классу, который не кажется правильным вообще и невозможен при обычных обстоятельствах где у меня нет доступа к базовому классу.

+0

Почему вы удаляете мо? – dtech

+0

@ddriver Я сделал это, пока не уверен, думал, так как это указатель, так как он обновляется на каждой итерации, которую я должен очистить? Или это ненужно полностью из-за того, что это QObject? – topher

+0

Не удаляйте его, вы идете в неопределенное поведение. Возвращаемый указатель просто указывает на метаобъект, он не выделяется динамически и не должен быть удален. – dtech

ответ

0

Vehicle наследует QObject, поэтому TransportVehicle придется использовать Q_OBJECT макро, Q_GADGET, когда вы не inherit QObject и хотите мета-объект.

Для каждого класса, который прямо косвенно наследует QObject, нужен макрос Q_OBJECT. У вас его нет в TransportVehicle, поэтому вы не получаете метаданные, созданные для него, вы застряли в мета-объекте, который был создан для базового класса.

+0

Итак, я сначала попытался, но получил «неопределенную ссылку на« vtable для ошибки TransportVehicle ». Что, насколько я помню, является аналогичной ошибкой, например, при попытке использовать классы шаблонов, класс наследования должен быть объявлен в тот же файл, что и базовый класс? Итак, что в том же случае с QObject? Я пробовал его, и он работает, но это единственный способ? Или можно использовать что-то вроде деклараций прямого класса? – topher

+0

@topher - попробуйте очистить все, запустить qmake и перестроить все из меню сборки – dtech

+0

Удивительная благодарность, которая получила его!Не могу поверить, что я потратил часы на это, потому что мне нужно было перестроить :) – topher

0

Вы отсутствуете использование макросов Q_OBJECT:

class TransportVehicle : public Vehicle 
{ 
    Q_OBJECT 
    ^^^^^^^^ 
    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; 
}; 

Для документации смотрите: http://doc.qt.io/qt-5/qobject.html#Q_OBJECT

+0

Я добавил Q_GADGET, но он делает то же самое, но я вижу staticMetaObject, как упоминалось в документах, но, глядя на это во время отладки, я все еще вижу только свойство модели ... любую идею? – topher

+0

Это неверно, 'Q_GADGET' предназначен для метаданных, но не наследует' QObject'. – dtech

+0

Спасибо. Починил это. – vcp