Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Dynamically get QML model of selected TreeView item



  • Hello. I'm creating a dynamic UI, where the user could choose which model item to display. To list model items I use Qt1.4 TreeView. I've created a working example of my code:
    main.qml

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Dialogs 1.2
    import QtQuick.Controls 2.12
    import QtQuick.Controls 1.4
    import QtQml.Models 2.11
    import QtQuick.Layouts 1.12
    
    import test.io.myModel 1.0
    
    Window {
        width: 240
        height: 280
        visible: true
    
        MyModel{
            id: myModel
        }
    
        RowLayout{
            TextField{
                id: textField
                property var modelIndex: undefined
                property var qmlModel: undefined
                text: qmlModel? qmlModel.value : "Item not chosen"
                onAccepted: {
                    if(modelIndex)
                        myModel.setValue(modelIndex, Number(textField.text));
                    else
                        text = "Item not chosen";
                    focus = false;
                }
            }
    
            Button{
                text: "Set param1"
                onClicked: {
                    textField.modelIndex = myModel.getIndex(0);
                    //How do I get QML model from TreeView?
                }
            }
        }
    
        TreeView{
            id: treeView
            y: 50
            model: myModel
            selection: ItemSelectionModel{
                id:mySelectionModel
                model: myModel
                onCurrentIndexChanged:{ }
            }
            itemDelegate: ItemDelegate{
                MouseArea{
                    anchors.fill: parent
                    onClicked: {
                        treeView.selection.setCurrentIndex(styleData.index, ItemSelectionModel.NoUpdate);
                        treeView.selection.select(styleData.index, ItemSelectionModel.ClearAndSelect);
                        treeView.selection.setCurrentIndex(styleData.index,ItemSelectionModel.SelectCurrent);
                    }
                    onDoubleClicked: {
                        textField.modelIndex = styleData.index
                        textField.qmlModel = model
                    }
                }
                Text{
                    text: styleData.value !== undefined ? styleData.value : ""
                    anchors.centerIn: parent
                }
            }
            TableViewColumn{
                title:"Name"
                role: "name"
                width: 100
            }
            TableViewColumn{
                title:"Value"
                role: "value"
                width: 100
                delegate: TextInput{
                    text: styleData.value !== undefined ? styleData.value :""
                    selectByMouse: true
                    onAccepted: {
                        myModel.setValue(styleData.index, Number(text));
                        focus = false;
                    }
                }
            }
        }
    }
    
    

    mymodel.h

    #ifndef MYMODEL_H
    #define MYMODEL_H
    
    #include <QObject>
    #include <QStandardItemModel>
    #include <QStandardItem>
    
    class MyModel : public QStandardItemModel
    {
        Q_OBJECT
    public:
        explicit MyModel(QObject *parent = nullptr);
        enum{
           Name =Qt::UserRole,
           Value
        };
        Q_INVOKABLE void setValue(const QModelIndex &index, double value);
        Q_INVOKABLE double getValue(const QModelIndex &index);
        Q_INVOKABLE QModelIndex getIndex(int row);
    
        QHash<int, QByteArray> roleNames() const override;
        QVector<MyModel> mItems;
    
    
    signals:
    
    };
    
    #endif // MYMODEL_H
    

    mymodel.cpp

    #include "mymodel.h"
    
    MyModel::MyModel(QObject *parent) : QStandardItemModel(parent)
    {
        for(int i = 0; i < 5; i++){
            QStandardItem *item = new QStandardItem;
            item->setData("Param"+QString::number(i+1), Name);
            item->setData(i, Value);
            appendRow(item);
        }
    
    }
    
    void MyModel::setValue(const QModelIndex &index, double value)
    {
        itemFromIndex(index)->setData(value, Value);
    }
    
    double MyModel::getValue(const QModelIndex &index)
    {
        return itemFromIndex(index)->data(Value).toDouble();
    }
    
    QModelIndex MyModel::getIndex(int row)
    {
        return index(row, 0);
    }
    
    QHash<int, QByteArray> MyModel::roleNames() const
    {
        QHash<int, QByteArray> names;
        names[Name] = "name";
        names[Value] = "value";
        return names;
    }
    

    What this code does: When I doubleclick an item in the TreeView I bind it to TextField, the value that the user chose is then interconnected between TreeView and TextField, I can change it on one component and it will be automatically updated in another through the property binding to my model. Now what each dynamic UI needs is save/load feature, so for this example I've added a Button, that should bind Parameter1 to TextField (as if it was done during the loading process). I can take QModelIndex directly from the C++ model, but can I get the QML model?


Log in to reply