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. QML receives undefined for roles from dataChanged signal
Forum Updated to NodeBB v4.3 + New Features

QML receives undefined for roles from dataChanged signal

Scheduled Pinned Locked Moved Solved QML and Qt Quick
14 Posts 2 Posters 7.6k Views 2 Watching
  • 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.
  • K Offline
    K Offline
    KiNgFrUiT
    wrote on last edited by KiNgFrUiT
    #5

    QML function and connection code is as follows:

        property var mode: 0
        property var status: 1
    
        function barrierDataChanged(topLeft, bottomRight, roles) {
            console.log("dataChanged", topLeft, bottomRight, roles, roles.length)
    
            var modelIndex = barrierModel.getBarrierIndex(barrierId)
    
            if(topLeft.row == modelIndex) {
                if(roles.contains("mode")) { // contains function is just a guess for now
                    mode = barrierModel.get(modelIndex).mode
                }
                else if(roles.contains("status")) { // contains function is just a guess for now
                    status = barrierModel.get(modelIndex).status
                }
            }
        }
    
        Connections {
            target: barrierModel
            onDataChanged: barrierDataChanged(topLeft, bottomRight, roles)
        }
    
    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #6

      Alright. What are you going to do once you get those values in barrierDataChanged ?
      I think you should probably rephrase your original question. I dont see any connection between your question I have a QAbstractItemListModel QAbstractListModel that works ok but updates are not very efficient, not all roles need to be updated. and the code you posted.

      157

      1 Reply Last reply
      0
      • K Offline
        K Offline
        KiNgFrUiT
        wrote on last edited by KiNgFrUiT
        #7

        Currently I need to update mode and status every time dataChanged is emitted, as I cannot tell which role has changed.

        If I can get the role parameter to contain useful data, instead of undefined, then the desired implementation will be more efficient as only the variable associated with the changed role needs updating.

        Existing Code:

            property var mode: 0
            property var status: 1
        
            function barrierDataChanged(topLeft, bottomRight) {
                var modelIndex = barrierModel.getBarrierIndex(barrierId)
        
                if(topLeft.row == modelIndex) {
                     mode = barrierModel.get(modelIndex).mode
                     status = barrierModel.get(modelIndex).status
                }
            }
        
            Connections {
                target: barrierModel
                onDataChanged: barrierDataChanged(topLeft, bottomRight)
            }
        

        Desired Code:

            property var mode: 0
            property var status: 1
        
            function barrierDataChanged(topLeft, bottomRight, roles) {
                console.log("dataChanged", topLeft, bottomRight, roles, roles.length)
        
                var modelIndex = barrierModel.getBarrierIndex(barrierId)
        
                if(topLeft.row == modelIndex) {
                    if(roles.contains("mode")) { // contains function is just a guess for now
                        mode = barrierModel.get(modelIndex).mode
                    }
                    else if(roles.contains("status")) { // contains function is just a guess for now
                        status = barrierModel.get(modelIndex).status
                    }
                }
            }
        
            Connections {
                target: barrierModel
                onDataChanged: barrierDataChanged(topLeft, bottomRight, roles)
            }
        
        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #8

          @KiNgFrUiT Are you talking something as shown in the following example ?
          http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#qabstractitemmodel-subclass

          157

          1 Reply Last reply
          0
          • K Offline
            K Offline
            KiNgFrUiT
            wrote on last edited by KiNgFrUiT
            #9

            Yes, in that example the Animal roles are type and size.
            In my application the roles are mode and status etc, I have simplified my code for this discussion.

                enum BarrierRole
                {
                    BarrierIdRole = Qt::UserRole + 1,
                    NameRole,
                    ModeRole,
                    StatusRole,
                    BulbCountRole,
                    BulbFaultsRole,
                    InductionLoopRole
                };
            
            p3c0P 1 Reply Last reply
            0
            • p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #10

              @KiNgFrUiT The only possibility left according to me(or try finding a way to make QVector available to QML, may be Q_DECLARE_METATYPE?? not sure) here is to create a Q_INVOKABLE in C++ model and call it from QML. This function will take arguments as both QModelIndex and the QVector<int> of roles. Then this function will resolve the values and return the data to QML.
              For eg:
              C++

              QVariant MyModel::getValueByRole(QModelIndex t, QModelIndex b, QVector<int> role)
              {
                  qDebug() << t.data(role[0]);
              }
              

              QML

              myModel.getValueByRole(topLeft, bottomRight, roles)
              

              157

              p3c0P 1 Reply Last reply
              0
              • K KiNgFrUiT

                Yes, in that example the Animal roles are type and size.
                In my application the roles are mode and status etc, I have simplified my code for this discussion.

                    enum BarrierRole
                    {
                        BarrierIdRole = Qt::UserRole + 1,
                        NameRole,
                        ModeRole,
                        StatusRole,
                        BulbCountRole,
                        BulbFaultsRole,
                        InductionLoopRole
                    };
                
                p3c0P Offline
                p3c0P Offline
                p3c0
                Moderators
                wrote on last edited by
                #11

                @KiNgFrUiT It works in Qt 5.7. I just went through the documentation on the web and the installed one. I was using Qt 5.6 earlier. There were differences. It seems that they have made available QVector<int> to QML in the latest version. If you are still looking for this issue try upgrading Qt to the latest version.

                157

                1 Reply Last reply
                1
                • p3c0P p3c0

                  @KiNgFrUiT The only possibility left according to me(or try finding a way to make QVector available to QML, may be Q_DECLARE_METATYPE?? not sure) here is to create a Q_INVOKABLE in C++ model and call it from QML. This function will take arguments as both QModelIndex and the QVector<int> of roles. Then this function will resolve the values and return the data to QML.
                  For eg:
                  C++

                  QVariant MyModel::getValueByRole(QModelIndex t, QModelIndex b, QVector<int> role)
                  {
                      qDebug() << t.data(role[0]);
                  }
                  

                  QML

                  myModel.getValueByRole(topLeft, bottomRight, roles)
                  
                  p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #12

                  @p3c0 But as expected it returns an int and since as per your code you require a string to compare you will need some additional code on CPP side to get role value from the key. For eg:

                  QString MyModel::getRoleValue(int key)
                  {
                      return roleNames().value(key);
                  }
                  

                  This will return rolename string using the key that you receive in onDataChanged handler's roles parameter. eg. roles[0], roles[1] ...

                  Or instead you can directly get the value using data() which requires a QModelIndex and the role.

                  var str = myModel.data(topLeft, roles[0])
                  

                  157

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    KiNgFrUiT
                    wrote on last edited by
                    #13

                    I just updated to 5.7, as per your suggestion, and everything works as expected.
                    Thank you so much for your assistance on this issue.

                    1 Reply Last reply
                    0
                    • p3c0P Offline
                      p3c0P Offline
                      p3c0
                      Moderators
                      wrote on last edited by
                      #14

                      @KiNgFrUiT You're Welcome :) Happy Coding.

                      157

                      1 Reply Last reply
                      0

                      • Login

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