覆盖QObject :: setProperty

时间:2014-09-10 07:36:31

标签: c++ qt properties

我想覆盖QObject::setProperty(const char*, QVariant),因为当我使用包含QVariant的{​​{1}}调用此方法时,该方法会失败,因为它不会将QVariantList转换为QVariantList

有什么建议吗?

修改

我有一个包含

的抽象类QList<UnknownType>
Node

Context* _context; QMap<QString, QString> _inputsPersisted; QMap<QString, QString> _outputsPersisted; 类还有一个Node和方法virtual void runImplementation(),如下所示:

void run()
     

}

void Node::run() { //get inputs from Context for(QMap<QString, QString>::iterator it = _inputsPersisted.begin() ; it != _inputsPersisted.end() ; ++it ) { QVariant attribute = property(it.key().toStdString().c_str()); if(!attribute.isValid()) { qWarning() << QObject::tr("%1:%2: Node::run:%3: the property %4 does not exist.").arg(__FILE__).arg(__LINE__).arg(_id.toString()).arg(it.key()); } else { QVariant v = _context->getDataPersisted(it.value()); if(!v.isValid()) qWarning() << QObject::tr("%1:%2: Node::run:%3: %4 is not in the context.").arg(__FILE__).arg(__LINE__).arg(_id.toString()).arg(it.value()); else if(v.type() != attribute.type()) qWarning() << QObject::tr("%1:%2: Node::run:%3: %4 and %5 have not the same type.").arg(__FILE__).arg(__LINE__).arg(_id.toString()).arg(it.key()).arg(it.value()); else if(!setProperty(it.key().toStdString().c_str(), v)) qWarning() << QObject::tr("%1:%2: Node::run:%3: the property %4 have not been setted.").arg(__FILE__).arg(__LINE__).arg(_id.toString()).arg(it.key()); } } runImplementation(); //set outputs in the Context for(QMap<QString, QString>::iterator it = _outputsPersisted.begin() ; it != _outputsPersisted.end() ; ++it ) { QVariant attribute = property(it.key().toStdString().c_str()); if(!attribute.isValid()) { qWarning() << QObject::tr("%1:%2: Node::run:%3: the property %4 does not exist.").arg(__FILE__).arg(__LINE__).arg(_id.toString()).arg(it.key()); } else { _context->setDataPersisted(it.value(), attribute); } } 类是这样的:

Context

有了这个,class Context : public QObject { Q_OBJECT public: Context(Context* parent = NULL) : : _parent(parent){} void setDataPersisted(QString name, QVariant value) { if(_parent != NULL && _parent->exist(name)) _parent->setDataPersisted(name, value); else { if(_stack.contains(name)) _stack.insert(name, value); else _stack.insert(name, value); } } QVariant getDataPersisted(QString name) { QVariant v; QMap<QString, QVariant>::iterator it = _stack.find(name); if(it != _stack.end()) v.setValue(it.value()); else if(_parent != NULL) v.setValue(_parent->getDataPersisted(name)); return v; } private: bool exist(QString name) { bool contains = _stack.contains(name); return contains || ((_parent != NULL) && (_parent->exist(name))); } private: Context * _parent; QMap<QString, QVariant> _stack; }; 子类可以在她的Node中放置并获取一些变量,而这只能通过声明她的属性并初始化Context_inputsPersisted来实现。所有逻辑都由_outputsPersisted类完成。

现在我想添加一种机制。我想操纵Node中的列表并执行Context。 为此,我修改了append方法:

Context::setDataPersisted

这样,在void setDataPersisted(QString name, QVariant value) { if(_parent != NULL && _parent->exist(name)) _parent->setDataPersisted(name, value); else { if(_stack.contains(name) && _stack.find(name)->value().canConvert(QVariant::List)) { QVariantList toChange = qvariant_cast<QVariantList>(_stack.find(name)->value()); toChange.append(value); _stack.insert(name, toChange ); } else _stack.insert(name, value); } } 之后,另一个setDataPersited(至“追加”)和setDataPersisted数据列表已损坏。

1 个答案:

答案 0 :(得分:0)

使用Q_DECLARE_METATYPE宏向Qt元类型系统注册QVariantList。这样可以将QVariantList存储为QVariant

    Q_DECLARE_METATYPE(QVariantList);
...
    QVariantList var;
    QVariant v = QVariant::fromValue<QVariantList>( var );
    QVariantList lst = v.value<QVariantList>();

QList<SomeType>转换为QVariantList

QList<SomeType> lst1;
...
QVariantList    lst2;

for (const SomeType& st : lst1)
    lst2.append( QVariant::fromValue<SomeType>( st ) ); 

QVariantList转换为QList<SomeType>

QVariantList    lst2;
...
QList<SomeType> lst1;

for (const QVariant& st : lst2)
    lst2.append( st.value<SomeType>() ); 

修改1:

auto it = _stack.find(name);
if (_stack.end() == it) {
    it = _stack.insert( name, QVariant::fromValue<QVariantList>(QVariantList()) );
}
QVariantList toChange = it->value().value<QVariantList>();
toChange.append(value);
_stack.insert(name, QVariant::fromValue<QVariantList>(toChange) );