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. QAbstractListModel - dataChanged
QtWS25 Last Chance

QAbstractListModel - dataChanged

Scheduled Pinned Locked Moved Solved QML and Qt Quick
19 Posts 4 Posters 11.1k 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.
  • G Offline
    G Offline
    goxx00
    wrote on last edited by goxx00
    #1

    Hey I am a newbie in Qt so please be gentle :)
    i write an application on the raspi which should display some measure sizes in real time. I get the values from a socket coonection to a PC. This connection is the base on my connection-class. This class runs in a second Thread. To display the values i have wrote an other class(page) which inherits from an QAbstractListModel. I display this Model in a GridView . My problem is when i change the values of the page class it should emit dataChanged() but my GUI doesnt changed.
    I tried the update the GridView with my own signal, by setting the model of the gridview to zero and than back to the data-model. But that was to much for my little raspi and i got an huge delay.
    So whats my Mistake?

    my setData function:
    bool Page::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    if(index.row()<0||index.row()>labels_p.size())
    return false;
    if(role=Qt::EditRole)
    {
    int row = index.row();
    labels_p[row].setvalue(value.toString().toStdString());
    emit dataChanged(QModelIndex(),QModelIndex());
    return true;
    }
    return false;

    }
    
    Julien BJ 1 Reply Last reply
    0
    • G goxx00

      Hey I am a newbie in Qt so please be gentle :)
      i write an application on the raspi which should display some measure sizes in real time. I get the values from a socket coonection to a PC. This connection is the base on my connection-class. This class runs in a second Thread. To display the values i have wrote an other class(page) which inherits from an QAbstractListModel. I display this Model in a GridView . My problem is when i change the values of the page class it should emit dataChanged() but my GUI doesnt changed.
      I tried the update the GridView with my own signal, by setting the model of the gridview to zero and than back to the data-model. But that was to much for my little raspi and i got an huge delay.
      So whats my Mistake?

      my setData function:
      bool Page::setData(const QModelIndex &index, const QVariant &value, int role)
      {
      if(index.row()<0||index.row()>labels_p.size())
      return false;
      if(role=Qt::EditRole)
      {
      int row = index.row();
      labels_p[row].setvalue(value.toString().toStdString());
      emit dataChanged(QModelIndex(),QModelIndex());
      return true;
      }
      return false;

      }
      
      Julien BJ Offline
      Julien BJ Offline
      Julien B
      wrote on last edited by
      #2

      Hello @goxx00 ,

      Have you try emit dataChanged(index, index); instead of emit dataChanged(QModelIndex(),QModelIndex()); ?

      1 Reply Last reply
      0
      • G Offline
        G Offline
        goxx00
        wrote on last edited by
        #3

        Thanks for your reply.
        I didnt work either.

        Julien BJ 1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by
          #4

          Hope you have put this code whenever you change the data in the model.

          beginInsertRows(QModelIndex(), rowCount(), rowCount());
          ....
          ....  
          endInsertRows();
          

          This should automatically update you UI.

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          1 Reply Last reply
          6
          • G Offline
            G Offline
            goxx00
            wrote on last edited by
            #5

            I used this function in my add function and this also doesn't update my GUI. But i will try.

             void Page::addLabel(const Label &label)
                {
            
                    beginInsertRows(QModelIndex(), rowCount(),rowCount());
                    labels_p<<label;
                    endInsertRows();
                }
            
            
            1 Reply Last reply
            0
            • G goxx00

              Thanks for your reply.
              I didnt work either.

              Julien BJ Offline
              Julien BJ Offline
              Julien B
              wrote on last edited by
              #6

              @goxx00,

              Can you show us your data method?

              Ps: I think there is a typo in your test if(role=Qt::EditRole) should be if(role==Qt::EditRole) with 2 '='

              1 Reply Last reply
              0
              • G Offline
                G Offline
                goxx00
                wrote on last edited by
                #7

                Thanks.

                 QVariant Page::data(const QModelIndex &index, int role) const
                    {
                        if(index.row() <0 || index.row() >= labels_p.count())
                            return QVariant();
                        const Label &label = labels_p[index.row()];
                        if (role==LabelnameRole)
                            return label.labelname();
                        else if (role==ValueRole)
                                    return label.value();
                        else if (role==UnitRole)
                                    return label.unit();
                        else if (role==DisplaytypRole)
                                    return label.displaytyp();
                        else if (role==DisplaysizeRole)
                                    return label.displaysize();
                        return QVariant();
                    }
                
                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  goxx00
                  wrote on last edited by
                  #8

                  Any advices ?

                  Julien BJ 1 Reply Last reply
                  0
                  • G goxx00

                    Any advices ?

                    Julien BJ Offline
                    Julien BJ Offline
                    Julien B
                    wrote on last edited by Julien B
                    #9

                    @goxx00

                    Try replacing if(role==Qt::EditRole) by if(role==ValueRole) in your setData method.

                    Are you sure your data is properly writed in labels_p in your code (checked with the debugger or a simple qDebug)?

                    How do you write your value data in your qml?

                    G 1 Reply Last reply
                    1
                    • E Offline
                      E Offline
                      Eeli K
                      wrote on last edited by
                      #10

                      You haven't shown your qml code, the problem might be there, in the view or delegate.

                      1 Reply Last reply
                      2
                      • Julien BJ Julien B

                        @goxx00

                        Try replacing if(role==Qt::EditRole) by if(role==ValueRole) in your setData method.

                        Are you sure your data is properly writed in labels_p in your code (checked with the debugger or a simple qDebug)?

                        How do you write your value data in your qml?

                        G Offline
                        G Offline
                        goxx00
                        wrote on last edited by
                        #11

                        @Julien-B said in QAbstractListModel - dataChanged:

                        Try replacing if(role==Qt::EditRole) by if(role==ValueRole) in your setData method.
                        Are you sure your data is properly writed in labels_p in your code (checked with the debugger or a simple qDebug)?

                        Now the values get updated in the labels_p. You were right. Before I corrected the typing error it worked too :D

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          goxx00
                          wrote on last edited by goxx00
                          #12
                           GridView {
                                              id:contentView
                                              anchors.fill: parent
                                              cellWidth: 200
                                              cellHeight: 105
                                              flow: GridView.FlowLeftToRight
                                              layoutDirection: Qt.LeftToRight
                                              verticalLayoutDirection: GridView.TopToBottom
                                              model: dataModel
                          
                          
                                              delegate: gridViewtemplate
                                          }
                          

                          ...

                          Component {
                                  id: gridViewtemplate
                          
                          
                                          Rectangle {
                                          width: 190
                                          height: 85
                                          color: "#4c4c4c"
                                               Label {
                                                   id:lname
                                                    anchors.horizontalCenter: parent.horizontalCenter
                                                    color: "#cccccc"
                                                    anchors.margins: 5
                                                    anchors.top: parent.top
                                                    text: labelname
                                                    font.pixelSize: 20
                                               }
                                               Label {
                                                   anchors.left: parent.left
                                                   color: "#cccccc"
                                                   anchors.bottom: parent.bottom
                                                   anchors.margins: 5
                                                   text: value
                                                   font.pixelSize: 25
                          
                                                  Label {
                                                      anchors.left: parent.right
                                                      color: "#cccccc"
                                                      anchors.verticalCenter: parent.verticalCenter
                                                      anchors.margins: 5
                                                      text: unit
                                                      font.pixelSize: 10
                                                  }
                                               }
                                        }
                          
                                }
                          

                          In my main.cpp I set the context property datamodel to an object of my Page class.

                          engine.rootContext()->setContextProperty("dataModel",connector.data2);
                          

                          connector is the class where i implemented my sockets and where I have the data2-object, which is a Page object. I am aiming for displaying the data2 object in the gridview.
                          The connector runs in a second thread.

                          G E 2 Replies Last reply
                          0
                          • G goxx00
                             GridView {
                                                id:contentView
                                                anchors.fill: parent
                                                cellWidth: 200
                                                cellHeight: 105
                                                flow: GridView.FlowLeftToRight
                                                layoutDirection: Qt.LeftToRight
                                                verticalLayoutDirection: GridView.TopToBottom
                                                model: dataModel
                            
                            
                                                delegate: gridViewtemplate
                                            }
                            

                            ...

                            Component {
                                    id: gridViewtemplate
                            
                            
                                            Rectangle {
                                            width: 190
                                            height: 85
                                            color: "#4c4c4c"
                                                 Label {
                                                     id:lname
                                                      anchors.horizontalCenter: parent.horizontalCenter
                                                      color: "#cccccc"
                                                      anchors.margins: 5
                                                      anchors.top: parent.top
                                                      text: labelname
                                                      font.pixelSize: 20
                                                 }
                                                 Label {
                                                     anchors.left: parent.left
                                                     color: "#cccccc"
                                                     anchors.bottom: parent.bottom
                                                     anchors.margins: 5
                                                     text: value
                                                     font.pixelSize: 25
                            
                                                    Label {
                                                        anchors.left: parent.right
                                                        color: "#cccccc"
                                                        anchors.verticalCenter: parent.verticalCenter
                                                        anchors.margins: 5
                                                        text: unit
                                                        font.pixelSize: 10
                                                    }
                                                 }
                                          }
                            
                                  }
                            

                            In my main.cpp I set the context property datamodel to an object of my Page class.

                            engine.rootContext()->setContextProperty("dataModel",connector.data2);
                            

                            connector is the class where i implemented my sockets and where I have the data2-object, which is a Page object. I am aiming for displaying the data2 object in the gridview.
                            The connector runs in a second thread.

                            G Offline
                            G Offline
                            goxx00
                            wrote on last edited by
                            #13
                            This post is deleted!
                            1 Reply Last reply
                            0
                            • G goxx00
                               GridView {
                                                  id:contentView
                                                  anchors.fill: parent
                                                  cellWidth: 200
                                                  cellHeight: 105
                                                  flow: GridView.FlowLeftToRight
                                                  layoutDirection: Qt.LeftToRight
                                                  verticalLayoutDirection: GridView.TopToBottom
                                                  model: dataModel
                              
                              
                                                  delegate: gridViewtemplate
                                              }
                              

                              ...

                              Component {
                                      id: gridViewtemplate
                              
                              
                                              Rectangle {
                                              width: 190
                                              height: 85
                                              color: "#4c4c4c"
                                                   Label {
                                                       id:lname
                                                        anchors.horizontalCenter: parent.horizontalCenter
                                                        color: "#cccccc"
                                                        anchors.margins: 5
                                                        anchors.top: parent.top
                                                        text: labelname
                                                        font.pixelSize: 20
                                                   }
                                                   Label {
                                                       anchors.left: parent.left
                                                       color: "#cccccc"
                                                       anchors.bottom: parent.bottom
                                                       anchors.margins: 5
                                                       text: value
                                                       font.pixelSize: 25
                              
                                                      Label {
                                                          anchors.left: parent.right
                                                          color: "#cccccc"
                                                          anchors.verticalCenter: parent.verticalCenter
                                                          anchors.margins: 5
                                                          text: unit
                                                          font.pixelSize: 10
                                                      }
                                                   }
                                            }
                              
                                    }
                              

                              In my main.cpp I set the context property datamodel to an object of my Page class.

                              engine.rootContext()->setContextProperty("dataModel",connector.data2);
                              

                              connector is the class where i implemented my sockets and where I have the data2-object, which is a Page object. I am aiming for displaying the data2 object in the gridview.
                              The connector runs in a second thread.

                              E Offline
                              E Offline
                              Eeli K
                              wrote on last edited by
                              #14

                              @goxx00 Does the grid show the values when it is shown the first time? Does Application Output in Qt Creator give any qml errors?

                              1 Reply Last reply
                              1
                              • G Offline
                                G Offline
                                goxx00
                                wrote on last edited by
                                #15

                                It shows nothing and in the application output occur no errors.
                                When I refresh the context property everytime I change something, then the model gets displayed.

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  goxx00
                                  wrote on last edited by
                                  #16

                                  When I update the context property after adding the labels it works. But this shows me that my addLabel function has a mistake or do i have to emit a signal when i add an item to my QList ?
                                  I thought the insertRows function do that.

                                  Thanks a lot for your help :)

                                  E 1 Reply Last reply
                                  0
                                  • G goxx00

                                    When I update the context property after adding the labels it works. But this shows me that my addLabel function has a mistake or do i have to emit a signal when i add an item to my QList ?
                                    I thought the insertRows function do that.

                                    Thanks a lot for your help :)

                                    E Offline
                                    E Offline
                                    Eeli K
                                    wrote on last edited by
                                    #17

                                    @goxx00 Basically the data() method should work because data is shown once. Unless you want to edit the values through the GUI (make them user editable) you don't need the setData function. You can just read or receive the values from the socket, store them in some form and then decide in your reading/receiving code what kind of signal should be emitted to notify the view about the changes. If the amount of rows stays the same, emit dataChanged with the indexes of the first and the last changed row. If rows are added, call begin/endInsertRows(). If much of the data is changed and the amount of rows changes, it's easiest to call begin/endResetModel().

                                    When the view receives a signal it automatically decides how to fetch and update the visible data. In any case it calls your model's data() function.

                                    I assume you have read the Subclassing section of the documentation and implemented rowCount and roleNames functions (probably it wouldn't work the first time unless you haven't).

                                    1 Reply Last reply
                                    2
                                    • G Offline
                                      G Offline
                                      goxx00
                                      wrote on last edited by
                                      #18

                                      Thank you very much. For sure, I have read the section and implemented the rowCount(), the flags() and the roleNames() functions. I hope I will get it it now.

                                      THANK YOU VERY MUCH!!!

                                      1 Reply Last reply
                                      0
                                      • G Offline
                                        G Offline
                                        goxx00
                                        wrote on last edited by
                                        #19

                                        Ok I am not ready yet :D I have the next problem maybe you can help me with it.
                                        When I add an Item to the QList, with the addLabel function I get an error:

                                        QObject::connect:: Cannot queue arguments of type 'QQmlChangeSet'
                                        (Make sure 'QQmlChangeSet' is registered using qRegisterMetaType().)
                                        

                                        I searched for a solution but I didnt found sth. that worked.
                                        I thin k it has to do with the fact that the object is in another Thread than the GUI.

                                        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