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. [solved] Newbie is confused.How to add dynamic data to TableView and parse through it send data to c++
Forum Updated to NodeBB v4.3 + New Features

[solved] Newbie is confused.How to add dynamic data to TableView and parse through it send data to c++

Scheduled Pinned Locked Moved QML and Qt Quick
42 Posts 3 Posters 15.9k Views 3 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.
  • p3c0P p3c0

    @vishnu No that is not updating. That wont invoke the data changed signal.
    As said earlier if you use append or remove use rowsInserted or rowsRemoved signals repectively.

    vishnuV Offline
    vishnuV Offline
    vishnu
    wrote on last edited by vishnu
    #33

    @p3c0
    you are right. This works perfect. I can see the data in c++ when ever a new row is added.

     QObject::connect(model,SIGNAL(rowsInserted(QModelIndex,int,int)),
                             &tcpCommunicationPort,SLOT(onRowsInserted(QModelIndex,int,int)));
    

    But when one of item in the Row is changed I can't see the new data in c++.So that means only Set/setproperty of ListModel will invoke the data changed signal. That mean My qml code is wrong if i want dataChangedsignal.
    I changed my TableView like this:

    TableView{
                id:setTableView
                objectName: "setTableView"
                model: {
                     setTableModel.set(0,{"x_position": 0,
                                           "y_position":300,
                                           "z_position":500,
                                           "velocity":0,
                                           "acceleration":0,
                                           "deceleration":0,
                                           "tool":0,
                                           "tracking_x":0,
                                           "tracking_y":0,
                                           "tracking_z":0});
                    setTableModel.set(1,{"x_position": 0,
                                          "y_position":400,
                                          "z_position":800,
                                          "velocity":0,
                                          "acceleration":0,
                                          "deceleration":0,
                                          "tool":0,
                                          "tracking_x":0,
                                          "tracking_y":0,
                                          "tracking_z":0})
                }
    

    Now the entire view if gone. I cannot add anymore rows.That means what I have done is wrong.But don't know what to do.
    Also If the user changes some value in any of the times.how can i know which value is changed? TableView has onClicked signal I can get the current row ,and delegate has access to the properties styleData.row - the index of the row ; styleData.column - the index of the column. Don't know how to make use of them.
    Can you please tell me what exactly have to be done on my QML side. Should i change my delegate or View or Model code?Thanks.

    p3c0P 1 Reply Last reply
    0
    • vishnuV vishnu

      @p3c0
      you are right. This works perfect. I can see the data in c++ when ever a new row is added.

       QObject::connect(model,SIGNAL(rowsInserted(QModelIndex,int,int)),
                               &tcpCommunicationPort,SLOT(onRowsInserted(QModelIndex,int,int)));
      

      But when one of item in the Row is changed I can't see the new data in c++.So that means only Set/setproperty of ListModel will invoke the data changed signal. That mean My qml code is wrong if i want dataChangedsignal.
      I changed my TableView like this:

      TableView{
                  id:setTableView
                  objectName: "setTableView"
                  model: {
                       setTableModel.set(0,{"x_position": 0,
                                             "y_position":300,
                                             "z_position":500,
                                             "velocity":0,
                                             "acceleration":0,
                                             "deceleration":0,
                                             "tool":0,
                                             "tracking_x":0,
                                             "tracking_y":0,
                                             "tracking_z":0});
                      setTableModel.set(1,{"x_position": 0,
                                            "y_position":400,
                                            "z_position":800,
                                            "velocity":0,
                                            "acceleration":0,
                                            "deceleration":0,
                                            "tool":0,
                                            "tracking_x":0,
                                            "tracking_y":0,
                                            "tracking_z":0})
                  }
      

      Now the entire view if gone. I cannot add anymore rows.That means what I have done is wrong.But don't know what to do.
      Also If the user changes some value in any of the times.how can i know which value is changed? TableView has onClicked signal I can get the current row ,and delegate has access to the properties styleData.row - the index of the row ; styleData.column - the index of the column. Don't know how to make use of them.
      Can you please tell me what exactly have to be done on my QML side. Should i change my delegate or View or Model code?Thanks.

      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #34

      @vishnu Keep your code with append and remove as it is. It just adds and removes the rows. Now to update the already added elements in ListModel use set.
      So,

      append -> rowsInserted
      remove -> rowsRemoved
      update i.e set -> dataChanged
      

      157

      vishnuV 1 Reply Last reply
      0
      • p3c0P p3c0

        @vishnu Keep your code with append and remove as it is. It just adds and removes the rows. Now to update the already added elements in ListModel use set.
        So,

        append -> rowsInserted
        remove -> rowsRemoved
        update i.e set -> dataChanged
        
        vishnuV Offline
        vishnuV Offline
        vishnu
        wrote on last edited by
        #35

        @p3c0
        I got the meaning what your saying but Where and how exactly I should do that set.
        For eg: should I do like this

        Button{
                        id:addNewRowButton
                        text: "ADD"
                        onClicked: {
                            setTableModel.append({"x_position": 0,
                                                     "y_position":0,
                                                     "z_position":0,
                                                     "velocity":0,
                                                     "acceleration":0,
                                                     "deceleration":0,
                                                     "tool":0,
                                                     "tracking_x":0,
                                                     "tracking_y":0,
                                                     "tracking_z":0}
                                                 )
        //ofcourse index is not defined, May be I make a property and increment it when even I add new row.
                            setTableModel.set(index,{"x_position": 0,
                                                  "y_position":0,
                                                  "z_position":0,
                                                  "velocity":0,
                                                  "acceleration":0,
                                                  "deceleration":0,
                                                  "tool":0,
                                                  "tracking_x":0,
                                                  "tracking_y":0,
                                                  "tracking_z":0})
                        }
        

        How about defalut values where should i set them?
        Is It in Tableview:this went totally wrong.

        id:setTableView
                    objectName: "setTableView"
                    model: {
                         setTableModel.set(0,{"x_position": 0,
                                               "y_position":300,
                                               "z_position":500,
                                               "velocity":0,
                                               "acceleration":0,
                                               "deceleration":0,
                                               "tool":0,
                                               "tracking_x":0,
                                               "tracking_y":0,
                                               "tracking_z":0});
        
        p3c0P 1 Reply Last reply
        0
        • vishnuV vishnu

          @p3c0
          I got the meaning what your saying but Where and how exactly I should do that set.
          For eg: should I do like this

          Button{
                          id:addNewRowButton
                          text: "ADD"
                          onClicked: {
                              setTableModel.append({"x_position": 0,
                                                       "y_position":0,
                                                       "z_position":0,
                                                       "velocity":0,
                                                       "acceleration":0,
                                                       "deceleration":0,
                                                       "tool":0,
                                                       "tracking_x":0,
                                                       "tracking_y":0,
                                                       "tracking_z":0}
                                                   )
          //ofcourse index is not defined, May be I make a property and increment it when even I add new row.
                              setTableModel.set(index,{"x_position": 0,
                                                    "y_position":0,
                                                    "z_position":0,
                                                    "velocity":0,
                                                    "acceleration":0,
                                                    "deceleration":0,
                                                    "tool":0,
                                                    "tracking_x":0,
                                                    "tracking_y":0,
                                                    "tracking_z":0})
                          }
          

          How about defalut values where should i set them?
          Is It in Tableview:this went totally wrong.

          id:setTableView
                      objectName: "setTableView"
                      model: {
                           setTableModel.set(0,{"x_position": 0,
                                                 "y_position":300,
                                                 "z_position":500,
                                                 "velocity":0,
                                                 "acceleration":0,
                                                 "deceleration":0,
                                                 "tool":0,
                                                 "tracking_x":0,
                                                 "tracking_y":0,
                                                 "tracking_z":0});
          
          p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #36

          @vishnu See

          • set is used to update the ListModel
          • since you have used TextInput to allow user to update the data you need a way to update the model from this. This can be done in onAccepted handler of TextInput
            So to sum up, for eg:
          delegate: TextInput {
              anchors.fill: parent
              text: styleData.value
              onAccepted: {
                  myModel.set( styleData.row, { title: text } ) //updates the role name "title" with updated text of TextInput
              }
          }
          

          157

          vishnuV 1 Reply Last reply
          0
          • p3c0P p3c0

            @vishnu See

            • set is used to update the ListModel
            • since you have used TextInput to allow user to update the data you need a way to update the model from this. This can be done in onAccepted handler of TextInput
              So to sum up, for eg:
            delegate: TextInput {
                anchors.fill: parent
                text: styleData.value
                onAccepted: {
                    myModel.set( styleData.row, { title: text } ) //updates the role name "title" with updated text of TextInput
                }
            }
            
            vishnuV Offline
            vishnuV Offline
            vishnu
            wrote on last edited by vishnu
            #37

            @p3c0
            Thanks for the explanation.Now I am not able to know which role is changed.
            As you said I did like this in QML.

            TableViewColumn {
                            role: "tracking_z"
                            title: "Tz mm"
                            delegate:
                                TextInput {
                                validator: IntValidator {}
                                text: styleData.value
                                onAccepted: {
                                setTableModel.set(styleData.row,{"tracking_z":parseInt(text)})
                                }
                            }
            

            For each column view I have a separate delegate because the IntValidator differs for each role.When ever there is datachanged this SLOT is called successfully.

            void TCPCommunicationPort::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
            {
                qDebug() << "row changed"<<topLeft.row();//getting the row number
                qDebug() << "column changed"<<topLeft.column();//this is always zero.I don't know why.
                QVariant newValue = topLeft.data(roles[0]);
                qDebug() << "Data Changed in cpp"<<newValue.toInt();//Getting the value where ever i change in the tableView.   
            //How to get the role name for which corresponding value is changed. 
            }
            

            Main problem is how to go the position where I have saved the tabledata to a position in Qbytearray.Can I access this model in onDataChanged SLOT?
            QAbstractListModel *model = qvariant_cast<QAbstractListModel *>(qmlmodel); //convert to QAbstractListModel
            Atleast I will try to read the whole new data(ofcourse it is insufficient) but my purpose is served.

            p3c0P 1 Reply Last reply
            0
            • vishnuV vishnu

              @p3c0
              Thanks for the explanation.Now I am not able to know which role is changed.
              As you said I did like this in QML.

              TableViewColumn {
                              role: "tracking_z"
                              title: "Tz mm"
                              delegate:
                                  TextInput {
                                  validator: IntValidator {}
                                  text: styleData.value
                                  onAccepted: {
                                  setTableModel.set(styleData.row,{"tracking_z":parseInt(text)})
                                  }
                              }
              

              For each column view I have a separate delegate because the IntValidator differs for each role.When ever there is datachanged this SLOT is called successfully.

              void TCPCommunicationPort::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
              {
                  qDebug() << "row changed"<<topLeft.row();//getting the row number
                  qDebug() << "column changed"<<topLeft.column();//this is always zero.I don't know why.
                  QVariant newValue = topLeft.data(roles[0]);
                  qDebug() << "Data Changed in cpp"<<newValue.toInt();//Getting the value where ever i change in the tableView.   
              //How to get the role name for which corresponding value is changed. 
              }
              

              Main problem is how to go the position where I have saved the tabledata to a position in Qbytearray.Can I access this model in onDataChanged SLOT?
              QAbstractListModel *model = qvariant_cast<QAbstractListModel *>(qmlmodel); //convert to QAbstractListModel
              Atleast I will try to read the whole new data(ofcourse it is insufficient) but my purpose is served.

              p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by p3c0
              #38

              @vishnu

              • Can I access this model in onDataChanged SLOT?
                -Yes. The QModelIndex also returns the model. Use topLeft.model()

              • How to get the role name for which corresponding value is changed.
                -Once you get the model using above method use roleNames().
                topLeft.model()->roleNames()[roles[0]]. This will give exact role name.

              • Atleast I will try to read the whole new data(ofcourse it is insufficient) but my purpose is served.
                -Ok. Would't that be unnecessary ?

              157

              vishnuV 1 Reply Last reply
              1
              • p3c0P p3c0

                @vishnu

                • Can I access this model in onDataChanged SLOT?
                  -Yes. The QModelIndex also returns the model. Use topLeft.model()

                • How to get the role name for which corresponding value is changed.
                  -Once you get the model using above method use roleNames().
                  topLeft.model()->roleNames()[roles[0]]. This will give exact role name.

                • Atleast I will try to read the whole new data(ofcourse it is insufficient) but my purpose is served.
                  -Ok. Would't that be unnecessary ?

                vishnuV Offline
                vishnuV Offline
                vishnu
                wrote on last edited by
                #39

                @p3c0
                perfect.served my purpose :) but inefficient solution :(.

                • Atleast I will try to read the whole new data(ofcourse it is insufficient) but my purpose is served.
                  -Ok. Would't that be unnecessary ?
                  because I have to send the data by array of char and I have saved the data from Tableview to char array like this:
                char m_senddataBuffer[3256]={0};//I know the max size
                char *positionValue;
                    positionValue = &m_senddataBuffer[56];//created a pointer to a particular position.
                    int count=0;
                    for (int i = 0; i<rows; i++) {
                        for(int j = model->roleNames().count()-1; j>=0; j--) { //get the roles count
                            QVariant rowData= model->index(i, 0).data(j); //get the actual data using roles
                            QString rolename = model->roleNames()[j];
                            int value =rowData.toInt();
                            //qDebug()<<" row"<<i << "role name"<<rolename<< "value "<<value;
                            if(!QString::compare(rolename,"x_position",Qt::CaseInsensitive))
                            {
                                qDebug()<<"x_position is running"<<++count;
                                value=value*1000;
                //int to char array
                                *(positionValue++) = (value) & 0xFF;
                                *(positionValue++) = (value >> 8) & 0xFF;
                                *(positionValue++) = (value >> 16) & 0xFF;
                                *(positionValue++) = (value >> 24) & 0xFF;
                            }
                //and so on...
                

                I just copy pasted the same code in onDataChanged SLOT. I thought of writing a function readModel(QAbstractItemModel model). but the typecased model is of type QAbstractListModel.So I have done like this. Any improvements can be done. Please let me know.

                p3c0P 1 Reply Last reply
                0
                • vishnuV vishnu

                  @p3c0
                  perfect.served my purpose :) but inefficient solution :(.

                  • Atleast I will try to read the whole new data(ofcourse it is insufficient) but my purpose is served.
                    -Ok. Would't that be unnecessary ?
                    because I have to send the data by array of char and I have saved the data from Tableview to char array like this:
                  char m_senddataBuffer[3256]={0};//I know the max size
                  char *positionValue;
                      positionValue = &m_senddataBuffer[56];//created a pointer to a particular position.
                      int count=0;
                      for (int i = 0; i<rows; i++) {
                          for(int j = model->roleNames().count()-1; j>=0; j--) { //get the roles count
                              QVariant rowData= model->index(i, 0).data(j); //get the actual data using roles
                              QString rolename = model->roleNames()[j];
                              int value =rowData.toInt();
                              //qDebug()<<" row"<<i << "role name"<<rolename<< "value "<<value;
                              if(!QString::compare(rolename,"x_position",Qt::CaseInsensitive))
                              {
                                  qDebug()<<"x_position is running"<<++count;
                                  value=value*1000;
                  //int to char array
                                  *(positionValue++) = (value) & 0xFF;
                                  *(positionValue++) = (value >> 8) & 0xFF;
                                  *(positionValue++) = (value >> 16) & 0xFF;
                                  *(positionValue++) = (value >> 24) & 0xFF;
                              }
                  //and so on...
                  

                  I just copy pasted the same code in onDataChanged SLOT. I thought of writing a function readModel(QAbstractItemModel model). but the typecased model is of type QAbstractListModel.So I have done like this. Any improvements can be done. Please let me know.

                  p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #40

                  @vishnu

                  perfect.served my purpose :) but inefficient solution :(.

                  What inefficient ?

                  157

                  vishnuV 1 Reply Last reply
                  0
                  • p3c0P p3c0

                    @vishnu

                    perfect.served my purpose :) but inefficient solution :(.

                    What inefficient ?

                    vishnuV Offline
                    vishnuV Offline
                    vishnu
                    wrote on last edited by
                    #41

                    @p3c0
                    reading the whole model when there is just one data has to be changed.

                    p3c0P 1 Reply Last reply
                    0
                    • vishnuV vishnu

                      @p3c0
                      reading the whole model when there is just one data has to be changed.

                      p3c0P Offline
                      p3c0P Offline
                      p3c0
                      Moderators
                      wrote on last edited by
                      #42

                      @vishnu Right that is why we have dataChanged :)

                      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