我正在尝试在QML界面中实现嵌套注释系统。我有一个C ++模型(从QAbstractListModel继承),其中模型中的每个项都返回两个值:一个是QString,另一个是带有roleName“dataMap”的QVariantMap。这适用于QML ListView。现在每个QVariantMap都包含一个“data”项,它还包含一个QVariantList“children”。现在,这基本上列出了具有相同结构的其他QVariantMaps。我实现这个的想法是在QML ListView中使用递归委托。下面是我最简单的代码版本。
ListView{
id: commentsList
anchors.fill: parent
model: commentsModel
delegate: commentsDelegate
}
Component{
id: commentsDelegate
ColumnLayout{
Rectangle{
width: 600
height: 200
Text {
id: bodyText
text: dataMap.body
anchors.centerIn: parent
Component.onCompleted: console.debug(text)
}
}
ListView{
id: childList
property var childModel: dataMap.replies.data.children // QVariantList exposed to QML
x: 15
interactive: false
model: childModel
anchors.fill: parent
delegate: commentsDelegate
}
}
}
我模型的结构如下:
class ListModel : public QAbstractListModel
{
Q_OBJECT
public:
ListModel(){}
explicit ListModel(QObject* parent =0);
~ListModel();
QHash<int, QByteArray> roleNames() const;
QVariant data(const QModelIndex & index, int role) const;
int rowCount(const QModelIndex &parent) const;
void addItem(ListItem item);
void clearModel();
private:
QList<ListItem> m_itemsList;
signals:
void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
};
ListItem类只是
class ListItem
{
public:
ListItem(QObject* parent = 0) : QObject(parent) {}
virtual ~ListItem() {}
ListItem(const QString & type, const QVariantMap & dataMap);
QString type() const;
QVariantMap dataMap() const;
private:
QString m_type;
QVariantMap m_dataMap;
现在这种方法不能用于多种原因(其中一个原因是 dataModel 中的 dataMap 属性可以作为 data 访问>,由任何QML项类型中的默认属性 data 覆盖。这个问题的任何可能的解决方案?
答案 0 :(得分:2)
我目前正在开发一个应用程序,它需要可视化大量(数亿个对象)树的孤立分支。由于它是一棵树,它与您的问题非常相似,这与嵌套模型有关。
我的解决方案是制作一种抽象形式。由于树已经存在并且是与GUI完全不同的设计层,因此我使用代理对象,该对象包含附加到可视化树节点的模型类。该模型只是列表视图的适配器,用于访问基础数据。
模型提供“对象”和“类型”角色,“根”委托用于实例化子节点的UI元素,对象角色用于创建附加到每个子节点的代理,如此有效,我得到了间接的嵌套模型。
每个委托基本上都是一个加载器(不是Loader
QML元素),它从模型角色接收指向每个对象及其类型的指针,因此它为该类型创建一个代理,以及一个UI元素type + ".qml"
附加到代理作为其数据源。
我不能分享任何代码,但希望你能得到这些代码。这种方法听起来有点复杂,但它提供了几个巨大的优势:
答案 1 :(得分:1)
我发现这篇非常有用的文章有助于解决问题https://lemirep.wordpress.com/2013/04/06/a-practical-case-exposing-qt-c-models-to-qml/。
该方法包括在模型类中创建另一个ListModel(从QAbstracListModel派生)。在我的示例中,我将QVariantMap dataMap()
替换为另一个ListModel dataModel()
。请注意,这也需要其他更改(可以在提供的链接中找到)