3

I have a QML TreeView with a QStandardItemModel and use a ItemSelectionModel to manage the selection. The ItemSelectionModel wants a QModelIndex for its select function. How can I obtain the QModelIndex of children in my view?

The tree looks like this:

  • file 1
    • task 1
    • task 2
  • file 2
    • task 1

I want to select task2 when I click on it (I can have a MouseArea in the delegate) (so that the TreeView highlights it), and in order to do this, I must call ItemSelectionModel.select with the QModelIndex of task 2. But I don' t know how I can get the QModelIndex of task2.

QStandardItemModel is derived from QAbstractItemModel and therefore provides an index function:

 virtual QModelIndex    index(int row, int column, const QModelIndex & parent = QModelIndex()) const

but to use this function I need to know the index of the parent. How can I get it from the view?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
maxwell
  • 357
  • 4
  • 14

1 Answers1

2

To obtain the child you must first have the parent, so in the case of your scheme you must obtain "file1" and for this you must obtain his parent, and this parent is the rootIndex of the TreeView, so the sequence is: rootIndex -> file1 -> task1.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardItemModel>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QStandardItemModel model;

    QStandardItem *item1 = new QStandardItem("file1");
    item1->appendRows({new QStandardItem("task1"), new QStandardItem("task2")});

    QStandardItem *item2 = new QStandardItem("file2");
    item2->appendRows({new QStandardItem("task1")});

    model.appendRow(item1);
    model.appendRow(item2);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("tree_model", &model);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQml.Models 2.11

Window {
    visible: true
    width: 640
    height: 480
    TreeView {
        id: treeView
        anchors.fill: parent
        model: tree_model
        selectionMode: SelectionMode.MultiSelection
        selection: ItemSelectionModel {
            id: ism
            model: tree_model
        }
        TableViewColumn {
            title: "Name"
            role: "display"
            width: 300
        }
        Component.onCompleted: {
            expandAll()

            var ix1 = tree_model.index(0, 0, treeView.rootIndex)
            var ix = tree_model.index(0, 0, ix1)
            ism.select(ix, ItemSelectionModel.Select)
        }
    }

    // https://forum.qt.io/topic/75395/qml-treeview-expand-method-not-working
    function expandAll() {
        for(var i=0; i < tree_model.rowCount(); i++) {
            var index = tree_model.index(i,0)
            if(!treeView.isExpanded(index)) {
                treeView.expand(index)
            }
        }
    }
}

enter image description here

Update:

To get the index of the item pressed you must use styleData.index:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQml.Models 2.11

Window {
    visible: true
    width: 640
    height: 480
    TreeView {
        id: treeView
        anchors.fill: parent
        model: tree_model
        selectionMode: SelectionMode.MultiSelection
        selection: ItemSelectionModel {
            id: ism
            model: tree_model
        }
        TableViewColumn {
            title: "Name"
            role: "display"
            width: 300
        }
        itemDelegate: Item {
            Text {
                anchors.verticalCenter: parent.verticalCenter
                color: styleData.textColor
                elide: styleData.elideMode
                text: styleData.value

            }
            MouseArea{
                anchors.fill: parent
                onClicked: {
                    var ix = tree_model.index(0, 0, styleData.index)
                    ism.select(ix, ItemSelectionModel.Select)
                }
            }
        }
    }
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I should have been more specific. The selection should happen via a click onto the MouseArea of a delegate. And the problem is to find the right ix1 (here file1) in the MouseArea of task1. – maxwell Sep 10 '18 at 20:24