Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to retrieve items indices from a treeView?
QtWS25 Last Chance

How to retrieve items indices from a treeView?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmltreeviewmodel-viewdelegatesindex
11 Posts 3 Posters 7.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Haitham
    wrote on 2 Jul 2017, 20:39 last edited by
    #1

    I don't know if the title is the most accurate one but here is the problem

    alt text

    As shown in the picture, I've built a TreeView list using QML (both delegate and treeview in QML) and a C++ Model.

    The problem is I don't know how to access the items through their indeces.
    For example if I were to retrieve the data of one item through its index I would only retrieve the parent item and not the child one

    for example
    (console.log(theModel.data(theModel.index(0,1),colView.role))
    would show me "Vision Status"

    if I tried to change "theModel.index(0,1)" to "theModel.index(1,0)"
    it won't retrieve anything and would return "undefined"

    I tried to console.log(styleData.index) but it would return me some gibberish that I can't make sense of

    for example
    if I pressed on "Camera connected" it would return
    QModelIndex(0,0,0x5573e70,MyTreeModel(0x5591b60))

    and pressing on its parent (Vision Status) would return
    QModelIndex(1,0,0x5573ce0,MyTreeModel(0x5591b60))

    this gibberish, the one written in hex, changes everytime I reload the program.
    so does anyone have any leads to this problem?

    The codes if someone wants to check on them

    main.qml

    import QtQuick 2.0
    import QtQuick.Controls 1.5
    import QtQuick.Controls.Styles 1.4
    import QtQuick.Window 2.2
    import MyTreeModel 1.0  //from qmlRegister in C++ code
    
    Rectangle
    {
        id:root
        height: 300
        width: 300
        property string sourceRed : "images/RedOff.png"
        //    property alias sourceRedAlias : root.sourceRed
    
        property string sourceGreen : "images/GreenOff.png"
        //    property alias sourceGreenAlias : root.sourceGreen
    
        MyTreeModel
        {
            id: theModel
        }
    
        MyTreeDelegate
        {
            id: theDelegate
        }
    
        MyBranchDelegate
        {
            id: theBranchDelegate
        }
    
        TreeView
        {
            id: treeView
            height: root.height
            width: root.width
            selectionMode: SelectionMode.NoSelection        //to hightlight selected items
            headerVisible: false    //to hide the header
            anchors.fill: root    //to fill rectangle
            highlightOnFocus: false
            model: theModel
    
            itemDelegate: theDelegate
            function expandTree()
            {
                //to expand the tree when initializing the program
                expand(theModel.index(0,0));
                expand(theModel.index(1,0));
                expand(theModel.index(2,0));
            }
    
            Component.onCompleted:
            {
                expandTree();
            }
    
    
            style: TreeViewStyle    //for styling the tree
            {
                backgroundColor: "white"
                alternateBackgroundColor:"white"
                //branch delegates are used for delegating the arrow on the left
                branchDelegate: theBranchDelegate
            }
    
            TableViewColumn
            {
                id: colView
                role: "name_role"
                title: "Status"
            }
        }
    }
    

    MyTreeDelegate.qml

    import QtQuick 2.0
    import QtQuick.Controls 1.4
    
    Component   //must wrap rectanlge inside a component QML type to be called from a different file
    {
        Rectangle
        {
    
            id:baseRec
            color: "transparent"
            //    color: ( styleData.row % 2 == 1 ) ? "white" : "#60e6dd"
            height: 5
    //            border.color: "black"
    //            border.width: 1
            states:
                [
                State
                {
                    name: "GreenOn"
                    PropertyChanges { target: green; source:"images/GreenOn.png"}
                    PropertyChanges { target: red; source:"images/RedOff.png" }
                },
    
                State
                {
                    name: "RedOn"
                    PropertyChanges { target: green; source:"images/GreenOff.png"}
                    PropertyChanges { target: red; source:"images/RedOn.png" }
                },
    
                State
                {
                    name: "BothOff"
                    PropertyChanges { target: green; source:"images/GreenOff.png"}
                    PropertyChanges { target: red; source:"images/RedOff.png" }
                },
    
                State
                {
                    name: "None"
                    PropertyChanges { target: green; source:""}
                    PropertyChanges { target: red; source:"" }
                }
            ]
    
            MouseArea
            {
                anchors.fill: parent
                onClicked:
                {
                    //                baseRec.state="RedOn"
                    //styleData.depth returns 0 for parents and 1 for children
                    console.log("row: ",styleData.row)
                    console.log("index: ",styleData.index)
                    console.log(theModel.data(theModel.index(1,0),colView.role));
                }
            }
    
            Text
            {
                anchors.verticalCenter: parent.verticalCenter
                text: ( styleData.value === undefined ) ? "" : styleData.value
                // The branches don't have a description_role so styleData.value will be undefined
            }
    
            //add two texts
            Image
            {
                id:red
                visible: !(styleData.depth === 0 ||
                           styleData.value==="Objects detected count"||
                           styleData.value==="Objects in pallet count")
    
                height: baseRec.height
                width: height
    
                source:  root.sourceRed //"images/RedOff.png"
    
                anchors
                {
                    verticalCenter:baseRec.verticalCenter
                    right:baseRec.right
                }
            }
    
            Image
            {
                id:green
                visible: !(styleData.depth === 0 ||
                           styleData.value==="Objects detected count" ||
                           styleData.value==="Objects in pallet count")
    
                height: baseRec.height
                width: height
    
                source: root.sourceGreen //"images/GreenOff.png"
                anchors
                {
                    verticalCenter:baseRec.verticalCenter
                    right:red.left
                }
            }
        }
    }
    

    MyTreeModel.cpp

    #include "mytreemodel.h"
    #include <QDebug>
    
    MyTreeModel::MyTreeModel(QObject *parent) : QStandardItemModel(parent)
    {
        m_roleNameMapping[MyTreeModel_Role_Name] = "name_role";
    
        addEntry("Listening","Communication Status");
        addEntry("Connected","Communication Status");
    
        addEntry("Camera connected","Vision Status");
        addEntry("Started","Vision Status");
        addEntry("Objects detected count","Vision Status");
    
        addEntry("Conveyor running","Palletizing Status");
        addEntry("Object picked up","Palletizing Status");
        addEntry("Objects in pallet count","Palletizing Status");
    
    
    }
    
    void MyTreeModel::addEntry(const QString &child, const QString &parent)
    {
    
    
        QStandardItem *childEntry = new QStandardItem(child); 
        QStandardItem *entry= getBranch(parent);
        entry->appendRow(childEntry);
    }
    
    QStandardItem *MyTreeModel::getBranch(const QString &branchName)
    {
        QStandardItem *entry;
        auto entries = this->findItems(branchName);
        if(entries.count() > 0)
        {
            entry = entries.at(0);
        }
        else
        {
            entry = new QStandardItem(branchName);
            this->appendRow(entry);
        }
        return entry;
    
    }
    
    QHash<int, QByteArray> MyTreeModel::roleNames() const
    {
        return m_roleNameMapping;
    }
    
    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on 3 Jul 2017, 07:28 last edited by
      #2

      Just add the third parameter to the index method:

      theModel.index(0,1) retrieves row 0, column 1 of the root
      theModel.index(0,1,theModel.index(0,0)) retrieves row 0, column 1 of the child of the first item in the root

      I hope this is clear enough

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      1
      • K Offline
        K Offline
        Kofr
        wrote on 3 Jul 2017, 08:09 last edited by
        #3

        Be aware that TreeView is very limited and has many bugs.
        Indexes are unsafe to use. You can find bugreports on qt bugreports.
        You may want to support https://bugreports.qt.io/browse/QTBUG-56490?filter=-2

        VRoninV H 2 Replies Last reply 3 Jul 2017, 09:29
        1
        • K Kofr
          3 Jul 2017, 08:09

          Be aware that TreeView is very limited and has many bugs.
          Indexes are unsafe to use. You can find bugreports on qt bugreports.
          You may want to support https://bugreports.qt.io/browse/QTBUG-56490?filter=-2

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on 3 Jul 2017, 09:29 last edited by
          #4

          @Kofr said in How to retrieve items indices from a treeView?:

          Indexes are unsafe to use

          Just to clarify: They are 100% safe to use in the C++ side

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          K H 2 Replies Last reply 3 Jul 2017, 11:50
          0
          • VRoninV VRonin
            3 Jul 2017, 09:29

            @Kofr said in How to retrieve items indices from a treeView?:

            Indexes are unsafe to use

            Just to clarify: They are 100% safe to use in the C++ side

            K Offline
            K Offline
            Kofr
            wrote on 3 Jul 2017, 11:50 last edited by
            #5

            @VRonin so far they are not manipulated by TreeView itself

            1 Reply Last reply
            0
            • K Kofr
              3 Jul 2017, 08:09

              Be aware that TreeView is very limited and has many bugs.
              Indexes are unsafe to use. You can find bugreports on qt bugreports.
              You may want to support https://bugreports.qt.io/browse/QTBUG-56490?filter=-2

              H Offline
              H Offline
              Haitham
              wrote on 3 Jul 2017, 12:19 last edited by
              #6

              @Kofr I've read your question one year ago, referring to this one

              That's why you are saying it has many bugs?

              let me clarify why I needed to retrieve the index, I'm trying to access each item on its own so I can apply a specific delegate to it (i.e. the green icon next to Camera connected will turn on if a specific condition is met on the back-end, that's why I tried to address each item on its own.

              So far the method VRonin provided worked well and gave me the data I expected, so I am hoping when I finish my code, manipulating the items through the back-end, the delegate will be applied correctly.

              I will keep you posted if I encountered any problem, thanks for the heads up.

              K 1 Reply Last reply 3 Jul 2017, 12:25
              0
              • H Haitham
                3 Jul 2017, 12:19

                @Kofr I've read your question one year ago, referring to this one

                That's why you are saying it has many bugs?

                let me clarify why I needed to retrieve the index, I'm trying to access each item on its own so I can apply a specific delegate to it (i.e. the green icon next to Camera connected will turn on if a specific condition is met on the back-end, that's why I tried to address each item on its own.

                So far the method VRonin provided worked well and gave me the data I expected, so I am hoping when I finish my code, manipulating the items through the back-end, the delegate will be applied correctly.

                I will keep you posted if I encountered any problem, thanks for the heads up.

                K Offline
                K Offline
                Kofr
                wrote on 3 Jul 2017, 12:25 last edited by
                #7

                @Haitham the problems begin occures when you make item moves in TreeView. After this operation items are shown incorrectly and you can not catch correct indexes unfortunataly.

                H 1 Reply Last reply 3 Jul 2017, 12:32
                1
                • VRoninV VRonin
                  3 Jul 2017, 09:29

                  @Kofr said in How to retrieve items indices from a treeView?:

                  Indexes are unsafe to use

                  Just to clarify: They are 100% safe to use in the C++ side

                  H Offline
                  H Offline
                  Haitham
                  wrote on 3 Jul 2017, 12:25 last edited by
                  #8

                  @VRonin
                  Thanks so much buddy, your method worked and I understood it, the problem with my method that I wasn't referring to a parent item so I can get its child.

                  What I eventually want to achieve is to let the delegates react to some back-end code, so I want to apply delegates to only a specific item once the condition is met (e.g., if Camera is connected, the green off icon should be replaced with a green on one) and so on. By saying so, I think it makes sense now why I wanted to be able to reach each item through its index.

                  Please, let me follow it by another question,
                  is it better to address the items on the C++ side or do it on the QML side?

                  VRoninV 1 Reply Last reply 3 Jul 2017, 12:35
                  0
                  • K Kofr
                    3 Jul 2017, 12:25

                    @Haitham the problems begin occures when you make item moves in TreeView. After this operation items are shown incorrectly and you can not catch correct indexes unfortunataly.

                    H Offline
                    H Offline
                    Haitham
                    wrote on 3 Jul 2017, 12:32 last edited by
                    #9

                    @Kofr

                    So far in my case, the items are all static and only the delegates are updated. I think I should not encounter this problem but we will see

                    Thanks a lot, once again!

                    1 Reply Last reply
                    1
                    • H Haitham
                      3 Jul 2017, 12:25

                      @VRonin
                      Thanks so much buddy, your method worked and I understood it, the problem with my method that I wasn't referring to a parent item so I can get its child.

                      What I eventually want to achieve is to let the delegates react to some back-end code, so I want to apply delegates to only a specific item once the condition is met (e.g., if Camera is connected, the green off icon should be replaced with a green on one) and so on. By saying so, I think it makes sense now why I wanted to be able to reach each item through its index.

                      Please, let me follow it by another question,
                      is it better to address the items on the C++ side or do it on the QML side?

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on 3 Jul 2017, 12:35 last edited by
                      #10

                      @Haitham said in How to retrieve items indices from a treeView?:

                      What I eventually want to achieve is to let the delegates react to some back-end code, so I want to apply delegates to only a specific item once the condition is met (e.g., if Camera is connected, the green off icon should be replaced with a green on one) and so on. By saying so, I think it makes sense now why I wanted to be able to reach each item through its index.

                      Just save the state as a separate role in the item and let the delegate check that role before deciding what to do

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      H 1 Reply Last reply 3 Jul 2017, 13:18
                      0
                      • VRoninV VRonin
                        3 Jul 2017, 12:35

                        @Haitham said in How to retrieve items indices from a treeView?:

                        What I eventually want to achieve is to let the delegates react to some back-end code, so I want to apply delegates to only a specific item once the condition is met (e.g., if Camera is connected, the green off icon should be replaced with a green on one) and so on. By saying so, I think it makes sense now why I wanted to be able to reach each item through its index.

                        Just save the state as a separate role in the item and let the delegate check that role before deciding what to do

                        H Offline
                        H Offline
                        Haitham
                        wrote on 3 Jul 2017, 13:18 last edited by Haitham 7 Mar 2017, 23:36
                        #11

                        @VRonin
                        Can you please provide an example or something to follow? Because I am still a newbie at both Qt and QML.
                        Sorry for bothering you with my many questions.

                        Update:
                        as you can see in the code, I change the state of the delegate through the mouse area in the delegate (it's commented out in the code). I was using it to test the states, now I've noticed another thing; Whenever I collapse the parent Item and then expand it, the previous states are not saved....does this have to do anything with what you mentioned?

                        1 Reply Last reply
                        0

                        1/11

                        2 Jul 2017, 20:39

                        • Login

                        • Login or register to search.
                        1 out of 11
                        • First post
                          1/11
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved