qml中的嵌套列表:模型中的数据模型

时间:2015-08-13 18:54:06

标签: c++ qt listview qml models

我正在尝试在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 覆盖。这个问题的任何可能的解决方案?

2 个答案:

答案 0 :(得分:2)

我目前正在开发一个应用程序,它需要可视化大量(数亿个对象)树的孤立分支。由于它是一棵树,它与您的问题非常相似,这与嵌套模型有关。

我的解决方案是制作一种抽象形式。由于树已经存在并且是与GUI完全不同的设计层,因此我使用代理对象,该对象包含附加到可视化树节点的模型类。该模型只是列表视图的适配器,用于访问基础数据。

模型提供“对象”和“类型”角色,“根”委托用于实例化子节点的UI元素,对象角色用于创建附加到每个子节点的代理,如此有效,我得到了间接的嵌套模型。

每个委托基本上都是一个加载器(不是Loader QML元素),它从模型角色接收指向每个对象及其类型的指针,因此它为该类型创建一个代理,以及一个UI元素type + ".qml"附加到代理作为其数据源。

我不能分享任何代码,但希望你能得到这些代码。这种方法听起来有点复杂,但它提供了几个巨大的优势:

  • 仅为所需的对象创建重Qt对象
  • 多个UI元素可以共享相同的代理和模型
  • 单个代表可以创建任意数量的完全不同的UI元素
  • 它适用于具有任意数量的具有不同属性的不同类型的树,并且它仅使用两个角色来实现它。每个对象都获得其唯一的UI元素,可通过代理访问底层对象的所有数据。祝你用动态角色实现这一目标
  • 代理还用于通知每个UI每个底层对象数据成员的数据变化

答案 1 :(得分:1)

我发现这篇非常有用的文章有助于解决问题https://lemirep.wordpress.com/2013/04/06/a-practical-case-exposing-qt-c-models-to-qml/。 该方法包括在模型类中创建另一个ListModel(从QAbstracListModel派生)。在我的示例中,我将QVariantMap dataMap()替换为另一个ListModel dataModel()。请注意,这也需要其他更改(可以在提供的链接中找到)