从另一个模型中提取子模型

Extracting sub model from a another model?

本文关键字:模型 提取 另一个      更新时间:2023-10-16

以下代码来自Qt演示。这是QTreeView的模型。

TreeItem下面的类表示树中的每个节点,它可以有子节点。

class TreeItem
{
public:
    explicit TreeItem(const QList<QVariant> &data, TreeItem *parentItem = 0);
    ~TreeItem();
    void appendChild(TreeItem *child);
    TreeItem *child(int row);
    int childCount() const;
    int columnCount() const;
    QVariant data(int column) const;
    int row() const;
    TreeItem *parentItem();
private:
    QList<TreeItem*> m_childItems;
    QList<QVariant> m_itemData;
    TreeItem *m_parentItem;
};

下面的TreeModel类是主要模型。它只包含一个根节点,该根节点包含所有其他子节点。

class TreeModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    explicit TreeModel(const QString &data, QObject *parent = 0);
    ~TreeModel();
    QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
    Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
    QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
    int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
    int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
private:
    void setupModelData(const QStringList &lines, TreeItem *parent);
    TreeItem *rootItem;
};

我正在使用QML,我可以在树中显示此模型,但是我也想在ListView中显示的模型。

对于列表视图,我只想一次显示一层(第一个孩子)。当用户单击任何项目时,它应清除并显示该项目子项。我该怎么做?

我的Qml代码在下面。它显示所有第一层子项,这很棒,但是当用户单击某个项目时,我需要显示子项。我的想法是需要提取子模型并指向它,但是如何?

Item {
    width: parent.width
    height: parent.height
    ListView {
        //anchors.top: myImage.bottom
        anchors.fill: parent
        id: list
        spacing: 4
        model: treeModel
        delegate: listDelegate
    }
    Component {
        id: listDelegate
        Rectangle
        {
            id: delegateRect
            height: image.height
            width: 500
            Image {
                id: image
                source: "qrc:/icons/resources/element.ico"
            }
            Text {
                id: t
                anchors.left: image.right
                anchors.leftMargin: 20
                anchors.centerIn: delegateRect
                text: title + "/" + summary
                //text: display
            }
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    list.currentIndex = index
                    console.log("Item clicked, index = " + index)
                    // I think I should change model here to sub model but how do I do it?
                    //list.model = treeModel.data(index) 
                }
            }
        }
    }
}

你应该看看Qt文档 http://doc.qt.io/qt-5/qabstractproxymodel.html 中的QAbstractProxyModel和派生类。

代理模型用于映射模型索引(如果要修改布局或对数据进行排序/筛选)和执行数据处理(修改从源模型数据方法返回的数据)。

您需要做的是添加一个属性来选择新的根(应该是提取模型的项的项)并实现mapFromSource(const QModelIndex &)mapToSource(const QModelIndex &)两种方法。这些方法将提供给视图的模型索引(仅在代理模型中有效)映射到基于当前设置的属性对源模型有效的模型索引(反之亦然)。

此外,您还应该重新实现 roleNames() 方法来转发源模型定义的角色名,以便能够从 QML 内部访问数据。