所以我有这样的想法,即使用Q_PROPERTY
的QObjects而不是QAbstractListModel
的角色名称,以便将需要通知的属性暴露给QML。
我的问题是,这是一个好的做法,因为使用从QAbstractItemModel
继承的类感觉有点不自然。
让我更详细地解释一下。
因此,为QML创建C ++模型的推荐方法是:
QAbstractListModel
(或其他人)以创建自定义模型。rowCount()
e.g:
enum DataRoles {
Name = Qt::UserRole + 1,
Description,
CustomData
};
...
QHash<int, QByteArray> TestList::roleNames() const
{
QHash<int, QByteArray> res;
res[static_cast<int>(DataRoles::Name)] = "name";
res[static_cast<int>(DataRoles::Description)] = "description";
res[static_cast<int>(DataRoles::CustomData)] = "customData";
return res;
}
data()
成员函数中返回相应的数据。e.g:
QVariant TestList::data(const QModelIndex & index, int role) const
{
QVariant result = QVariant();
if ( index.isValid() == true ) {
EntityPtr entityPtr = entities_.at(index.row());
switch (role) {
case DataRoles::Name:
result = entityPtr->name();
break;
case DataRoles::Description:
result = entityPtr->description();
break;
case DataRoles::CustomData:
result = entityPtr->customData();
break;
}
}
return result;
}
然后,在QML的上下文中注册模型实例后,您可以按名称访问ListView委托中的实体字段,在rolesNames()中定义,例如:
ListView {
model: yourModelInstance
...
delegate: Item {
...
Text {
text: name // access DataRoles::Name
}
...
}
}
IMO,这个实现都很好,但是当涉及到从C ++方面更改属性时,应该在实体属性的每次更改时调用QAbstractListView
的dataChaged()信号。 / p>
我希望能够自动通知有关更改的信息,例如当我打电话给entity->setName()
时。
我想到的是只注册一个数据角色,例如“object”将返回整个QObject,它将具有Q_PROPERTY
s然后从qml访问它,如:
Text {
text: object.name //access `name` Q_PROPERTY of the object
}
这样,如果setters将发出正确的信号,在Q_PROPERTY声明中注册,QML端将自动通知设置新值的变化。
所以问题是,如果这是实现我的目标的一个好方法,因为,正如我上面所说,它感觉有点不自然,Qt库是一个很好的表明你做错了做错事很难(不自然)。
修改:
正如评论中所要求的,我已经制作了一个小型的Qt示例应用程序,展示了我想要实现的目标。
答案 0 :(得分:0)
我认为你需要在每个属性的Entity中使用propertyChanged信号。然后将propertyChanged链接到dataChanged信号。当你设置name或setPosition时,发出propertyChanged signal。