The following code is from a Qt demo. This is a model for QTreeView.
TreeItem class below represent each node in tree, it can have child nodes.
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 below is the main model. It only contains one root node which contain all other child nodes.
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;
};
I am using QML and I can get this model displayed in tree however I also want to display in a ListView.
For the ListView, I only want to display one tier at one time (1st childrens). When user click on any of the item, it should clear and show that item children. How do I do that?
My Qml code is below. It displays all first tier children which is great but I need to show children when user clicks on an item. My thought is need extract the sub model and point to it, but how?
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) 
                }
            }
        }
    }
}
You should have a look at the QAbstractProxyModel and derived classes in the Qt documentation http://doc.qt.io/qt-5/qabstractproxymodel.html.
A proxy model is used to map model indexes (if you want to modify the layout, or do sorting/filtering on data) and do data processing (modify the data returned from the source models data method).
What you need to do is to add a property to select the new root (the item that should be the root item of the extracted model) and implement the two methods mapFromSource(const QModelIndex &) and mapToSource(const QModelIndex &). These methods map the model index given to the view (and only valid in your proxy model) to a model index that is valid for the source model based on the currently set root property (and vice versa).
In addition you should also reimplement the roleNames() method to forward the rolenames defined by the source model to be able to access the data from inside QML.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With