2010-04-01 4 views
4

Я зарегистрировал тип перечисления «ClefType» в моем файле заголовка - это перечисление зарегистрировано в системе MetaObject с использованием макросов Q_DECLARE_METATYPE и Q_ENUMS. qRegisterMetaType также вызывается в конструкторе класса.Доступ к перечислению, хранящемуся в QVariant

Это позволяет мне использовать этот тип в Q_PROPERTY, все это прекрасно работает. Однако позже я должен уметь получить Q_PROPERTY этого типа перечисления, учитывая, что объект - в форме, подходящей для сериализации.

В идеале, было бы полезно, чтобы сохранить целое значение для этого элемента перечисления, потому что я не хочу, чтобы это быть специфическими для типа перечисления, который используется - в конце концов, я хочу иметь несколько различных перечислений.

// This is inside a loop over all the properties on a given object 
QMetaProperty property = metaObject->property(propertyId); 
QString propertyName = propertyMeta.name(); 
QVariant variantValue = propertyMeta.read(serializeObject); 

// If, internally, this QVariant is of type 'ClefType', 
// how do I pull out the integer value for this enum? 

variantValue.toInt(); К сожалению, не работает - пользовательские перечисления не кажется непосредственно «колдовать» до целого значения.

Спасибо заранее,

Генри

ответ

0

Вы можете использовать >> и << операторы QVariant для достижения этой цели.

Saving (где MyClass *x = new MyClass(this); и out является QDataStream):

const QMetaObject *pObj = x->pObj(); 
for(int id = pObj->propertyOffset(); id < pObj->propertyCount(); ++id) 
{ 
    QMetaProperty pMeta = pObj->property(id); 
    if(pMeta.isReadable() && pMeta.isWritable() && pMeta.isValid()) 
    { 
     QVariant variantValue = pMeta.read(x); 
     out << variantValue; 
    } 
} 

Загрузка:

const QMetaObject *pObj = x->pObj(); 
for(int id = pObj->propertyOffset(); id < pObj->propertyCount(); ++id) 
{ 
    QMetaProperty pMeta = pObj->property(id); 
    if(pMeta.isReadable() && pMeta.isWritable() && pMeta.isValid()) 
    { 
     QVariant variantValue; 
     in >> variantValue; 
     pMeta.write(x, variantValue); 
    } 
} 

Вам нужно будет позвонить

qRegisterMetaType<CMyClass::ClefType>("ClefType"); 
    qRegisterMetaTypeStreamOperators<int>("ClefType"); 

в дополнение к использованию Q_OBJECT, Q_ENUMS и Q_PROPERTY. Вызов qRegisterMetaTypeStreamOperators<int> сообщает Qt, чтобы использовать int-версии operator<< и operator>>.

Кстати: использование qRegisterMetaType<CMyClass::ClefType>() вместо формы, которая берет имя, не работает для меня. Это может быть, если вы использовали возвращенный идентификатор для поиска имени, но это намного проще.

FYI, вот MyClass определение:

class CMyClass : public QObject 
{ 
    Q_OBJECT 
    Q_ENUMS(ClefType) 
    Q_PROPERTY(ClefType cleftype READ getCleftype WRITE setCleftype) 
public: 
    CMyClass(QObject *parent) : QObject(parent), m_cleftype(One) 
    { 
     qRegisterMetaType<CMyClass::ClefType>("ClefType"); 
     qRegisterMetaTypeStreamOperators<int>("ClefType"); 
    } 
    enum ClefType { Zero, One, Two, Three }; 
    void setCleftype(ClefType t) { m_cleftype = t; } 
    ClefType getCleftype() const { return m_cleftype; } 
private: 
    ClefType m_cleftype; 
}; 

Q_DECLARE_METATYPE(CMyClass::ClefType) 
+0

Это отлично работает - большое спасибо за ваш ответ в глубину! Очень признателен –

1

Try:

int x = variantValue.value<ClefType>(); 
+0

Хотя это будет работать специально для ClefType, мне идеально понравилось бы работать для любого перечисленного типа. –

1

У меня была такая же проблема, и придумал ниже решение, которое работает для любого перечислимого типа:

int x = property.enumerator().value(*reinterpret_cast<const int *>(variantValue.constData())); 
Смежные вопросы