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

Accessing QAbstractItemModel fields in QML



  • hi,
    I am trying to access model (QAbstractItemModel ) fields inside the itemDelegate of a QML TreeView (QtQuick.Controls 1.4)

    I'm able to show the field i need using TableViewColumn and implementing roleNames() method

    TableViewColumn {
               title: "isSub"
               role: "sub"
               width: 100
           }
    
    QHash<int, QByteArray> OpcUaModel::roleNames() const
    {
            QHash<int, QByteArray> roles;
            roles[NodeSubActive] = "sub";
            return roles;
    }
    

    this works as expected, it shows the value of my sub variable.

    My problem is that I don't know how to access to that variable from somwhere else like :

    itemDelegate: Text {
               text: styleData.value
               color: myUaModel.sub   ? "blue" : "red"
              // or   color: styleData.sub  ? "blue" : "red"
           }
    

    Can someone tell how this should be done please ?

    Thank you


  • Moderators

    @LeLev
    a variable is attached to each item delegate instance according to the item/row displayed
    so simply use the roleName in the delegate context

    Edit: ah, i misread. you are using controls1

    as a workaround you can add a custom invokable method which gives you the role value for "styleData.row". This custom invokable method, simply calls data() with the itemrole value taken from roleNames()


  • Moderators

    @LeLev
    a variable is attached to each item delegate instance according to the item/row displayed
    so simply use the roleName in the delegate context

    Edit: ah, i misread. you are using controls1

    as a workaround you can add a custom invokable method which gives you the role value for "styleData.row". This custom invokable method, simply calls data() with the itemrole value taken from roleNames()



  • hi, thank you very much for your answer
    @raven-worx said in Accessing QAbstractItemModel fields in QML:

    as a workaround you can add a custom invokable method which gives you the role value for "styleData.row". This custom invokable method, simply calls data() with the itemrole value taken from roleNames()

    I was trying to do that but i was wondering if things will get refreshed correctly, I will try and let you know.



  • @raven-worx hi
    I am trying to write the q_invokable method you suggested to me but i have lots of troubles, this is what i try

    itemDelegate: Text {
         text: styleData.value 
         color: myUaModel.getSubActiveByIndex(styleData.row,styleData.column) ? "green" : "blue"
    }
    
      Q_INVOKABLE bool getSubActiveByIndex(int r, int c){ 
            qDebug() << "r : " << r << ";" << "c : " << c;
            QModelIndex idx = QAbstractItemModel::createIndex(r,c);
            qDebug() << "ModelIndex : " << idx;
            if(idx.isValid()){
                auto item = static_cast<TreeItem *>(idx.internalPointer());
                qDebug()  << item; // always outputs QObject(0x0)
            }else{
                qDebug()<< "Bad qModelIndex";
            }
    

    i get this output when i show the tree view in QML, this are the 3 children of my root node, but it looks like i already have an issue here because qDebug() << item; shows QObject(0x0)

    r :  0 ; c :  0
    ModelIndex :  QModelIndex(0,0,0x0,OpcUaModel(0x127b460))
    QObject(0x0)
    r :  0 ; c :  1
    ModelIndex :  QModelIndex(0,1,0x0,OpcUaModel(0x127b460))
    QObject(0x0)
    r :  0 ; c :  2
    ModelIndex :  QModelIndex(0,2,0x0,OpcUaModel(0x127b460))
    QObject(0x0)
    

    Then if i access items attributes or data() method, obviously my app crashes, do you see what I did wrong ?

    To me it looks like i'm doing something wrong about QModelIndex creation, because if i pass the QModelIndex directly from qml to c++ like this :

    TreeView{
        onDoubleClicked: myUaModel.subscribe(index)
    }
    //c++
    Q_INVOKABLE void subscribe(QModelIndex ind ){
           auto item = static_cast<TreeItem *>(ind.internalPointer());
    // ...
    }
    

    this way i can construct and interact with the TreeItems.
    The probleme is that index is not avalable in the itemDelegate, thats why i pass styleData.row and styleData.column

    color : myUaModel.getSubActiveByIndex(styleData.row,styleData.column) ? "green" : "red"
    

    and try construct the QModelIndex in cpp

    Q_INVOKABLE bool getSubActiveByIndex(int r, int c){
      QModelIndex idx = QAbstractItemModel::createIndex(r,c); 
    

    TreeItem and the model class come from this example : https://doc.qt.io/QtOPCUA/qtopcua-opcuaviewer-example.html (i'm just trying to change the view from QtreeView to QML TreeView. My first post about this )



  • @LeLev said in Accessing QAbstractItemModel fields in QML:

    To me it looks like i'm doing something wrong about QModelIndex creation, because if i pass the QModelIndex directly from qml to c++ like this :

    indeed this was the problem, instead of passing styleData.row and styleData.column to my Q_Invokable method i can pass
    styleData.index

    itemDelegate: Text {
     color:  myUaModel.getSubActiveByIndex(styleData.index) ? "green" : "blue"
    }
    
    Q_INVOKABLE bool getSubActiveByIndex(QModelIndex ind){
            bool isSub = false;
            if(!ind.isValid()) return isSub;
    
            auto item = static_cast<TreeItem *>(ind.internalPointer());
            isSub = item->data(7).toBool();
            return isSub;
        }
    

Log in to reply