[Request] TreeView C++ model to qml example



  • I found this example for creating a tree model: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

    The issue is that using the model in the qml doesn't display anything, and creating the QTreeView instead DOES show it correctly..

    main.cpp (without main def):

    QGuiApplication app(argc, argv);
    QQmlEngine engine;
    
    QString data = ...
    MyTreeModel myTreeModel = MyTreeModel(data);
    engine.rootContext()->setContextProperty("MyTreeModel", &myTreeModel);
    
    QQmlComponent component(&engine, QUrl("qrc:/main.qml"));
    component.create();
    return app.exec();
    

    main.qml:

    ApplicationWindow {
        title: "TestWindow"
        width: 640
        height: 480
        visible: true
    
        TreeView {
            id: treeView
            anchors.fill: parent
            model: MyTreeModel
        }
    }
    

    If instead of executing the qml I do this, it shows correctly (same model instantiation beforehand):

    [...]
    QApplication app(argc, argv);
    QTreeView tree;
    tree.setModel(&myTreeModel);
    tree.show();

  • Moderators

    Hi @Pheelbert,
    I think you may have missed re-implementing roleNames function in the model. QML views rely on these. Without them the model doesn't understand what to return. I had explained a similar one here. So basically you have to add the following in C++ model:

    • re-implement roleNames
    • define the role names
    QHash<int, QByteArray> MyModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[TitleRole] = "Title";  //these should match exactly with that in QML
        roles[SummaryRole] = "Summary"; //these should match exactly with that in QML
        return roles;
    }
    
    enum TreeRoles {
        TitleRole = Qt::UserRole + 10,
        SummaryRole = Qt::UserRole + 11
    };
    

    Apart from that I hope you have initialized the model and set it as a context Property to access it from QML.
    For eg:
    in main.cpp or any where as per you need

    TreeModel model;
    
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("myModel",&model);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); //access myModel in QML
    


  • @p3c0 Thank you so much, I also had to change to this too afterwards (removed the check if role != Qt.DisplayRole ):

    QVariant MyTreeModel::data(const QModelIndex& index, int role) const {
        if (!index.isValid())
            return QVariant();
    
        MyTreeItem* item = static_cast<MyTreeItem*>(index.internalPointer());
    
        switch (role) {
        case TitleRole:
            return item->data(0);
        case SummaryRole:
            return item->data(1);
        default:
            return QVariant();
        }
    }
    

    Also, there's a "root item" that I would much rather not have; not a big deal I'll find a way work around that!


  • Moderators

    @Pheelbert Yes missed the mentioning of data() here.
    You're Welcome :-) Happy Coding.