Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to modify the data in the model and update the view when new data is received from external?
Forum Updated to NodeBB v4.3 + New Features

How to modify the data in the model and update the view when new data is received from external?

Scheduled Pinned Locked Moved Solved General and Desktop
76 Posts 4 Posters 55.0k Views 1 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.
  • S SGaist
    30 Aug 2018, 20:49

    How exactly are you getting new data ?
    What are these new data ?
    One object update ?
    Several objects update ?
    How do they fit in your model internal representation ?

    ? Offline
    ? Offline
    A Former User
    wrote on 30 Aug 2018, 21:01 last edited by A Former User
    #14

    @SGaist : I am getting this data when user clicks left mouse button. I have slot, so when user clicks button some magic is done and later i save in model member variable Info_.
    The NewStructInfo looks like this:
    struct NewStructInfo{
    double x;
    double y;
    } Info_;
    So now my model data categories_ looks something like this:
    ```
    Property ----------------------------------------- Value
    -->Coordinates(categoryitem pointer)
    ------X (scenariopropertyitem1 pointer type) ------ "Empty"
    ------Y (scenariopropertyitem pointer type) -------- "Empty"

    The above structure you can see in parsejsonobject member function. Now in the above categories_ model data i have iterate along category->secnariopropertyitem and look for the name i,e,

    if(scenariopropertyitem->name == x)
    // scenariopropertyitem pointer has name as class member
    scenariopropertyitem->setValue(QVariant(Info_.X));
    Now somehow dataChanged(??,??,Qt::displayrole) has to be called.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 30 Aug 2018, 21:11 last edited by
      #15

      Since you have to go through your model to find the correct item to update, you should already have the index matching the scenariopropertyitem you found, no ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      ? 1 Reply Last reply 30 Aug 2018, 21:13
      1
      • S SGaist
        30 Aug 2018, 21:11

        Since you have to go through your model to find the correct item to update, you should already have the index matching the scenariopropertyitem you found, no ?

        ? Offline
        ? Offline
        A Former User
        wrote on 30 Aug 2018, 21:13 last edited by A Former User
        #16

        @SGaist : How would i access it or get the index of the item? Meanwhile would you suggest me to use third option from this answer: https://stackoverflow.com/questions/29921041/getting-the-index-for-a-given-item-in-a-qtreeview-model-application.
        Could you provide an example?

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on 30 Aug 2018, 21:23 last edited by A Former User
          #17
          This post is deleted!
          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on 31 Aug 2018, 05:24 last edited by
            #18
            This post is deleted!
            1 Reply Last reply
            0
            • V Offline
              V Offline
              VRonin
              wrote on 31 Aug 2018, 07:48 last edited by
              #19

              What I always suggest is that if you are not 100% confident in your model design (and, believe me, it's a hard) just use QAbstractItemModel* model = new QStandardItemModel(parent). Then use insertRows, insertColumns, and setData to setup your model

              "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
              0
              • ? Offline
                ? Offline
                A Former User
                wrote on 31 Aug 2018, 08:01 last edited by
                #20

                In my Model.cpp i did the following:

                    emit beginResetModel();
                    for (auto& category : categories_) {
                        category->entryAt(0)->setValue(1);
                        // for testing  i just set randomly my data value to 1
                    }
                    emit endResetModel();
                

                But after above changes the view is not displaying the new values.

                J 1 Reply Last reply 31 Aug 2018, 08:06
                0
                • ? A Former User
                  31 Aug 2018, 08:01

                  In my Model.cpp i did the following:

                      emit beginResetModel();
                      for (auto& category : categories_) {
                          category->entryAt(0)->setValue(1);
                          // for testing  i just set randomly my data value to 1
                      }
                      emit endResetModel();
                  

                  But after above changes the view is not displaying the new values.

                  J Offline
                  J Offline
                  JonB
                  wrote on 31 Aug 2018, 08:06 last edited by
                  #21

                  @VInay123
                  I don't see any entryAt() function in Qt. So what type is category, what does category->entryAt(0)->setValue(1) do in the way of setting anything in the model??

                  ? 1 Reply Last reply 31 Aug 2018, 08:13
                  0
                  • J JonB
                    31 Aug 2018, 08:06

                    @VInay123
                    I don't see any entryAt() function in Qt. So what type is category, what does category->entryAt(0)->setValue(1) do in the way of setting anything in the model??

                    ? Offline
                    ? Offline
                    A Former User
                    wrote on 31 Aug 2018, 08:13 last edited by
                    #22

                    @JonB: If you see my code Category is a class which has entryAt() function which returns back the propertyitem. So here i am setting the model data i.e. my categories_ member variable in the model class.

                    J 1 Reply Last reply 31 Aug 2018, 08:26
                    0
                    • ? A Former User
                      31 Aug 2018, 08:13

                      @JonB: If you see my code Category is a class which has entryAt() function which returns back the propertyitem. So here i am setting the model data i.e. my categories_ member variable in the model class.

                      J Offline
                      J Offline
                      JonB
                      wrote on 31 Aug 2018, 08:26 last edited by
                      #23

                      @VInay123
                      OK for entryAt(). But where in your code does entryAt(0)->setValue(1) call QAbstractModel::setData() (http://doc.qt.io/qt-5/qabstractitemmodel.html#setData)? Where is the http://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged signal being emitted?

                      ? 1 Reply Last reply 31 Aug 2018, 08:28
                      0
                      • J JonB
                        31 Aug 2018, 08:26

                        @VInay123
                        OK for entryAt(). But where in your code does entryAt(0)->setValue(1) call QAbstractModel::setData() (http://doc.qt.io/qt-5/qabstractitemmodel.html#setData)? Where is the http://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged signal being emitted?

                        ? Offline
                        ? Offline
                        A Former User
                        wrote on 31 Aug 2018, 08:28 last edited by A Former User
                        #24

                        @JonB: That is the problem i am facing. I do not know how to call setData which in turn emits the signal dataChanged. I do not know how to get the indexes. Here the data is only coming from the "Info_" variable. If the it was via delegates or adapters i could easily get the indexes and call setData. But in my case i get in a structure and go through each item and update its value. Could you please show me how can i achieve this in my code i.e. change the value via setData?

                        J 1 Reply Last reply 31 Aug 2018, 08:50
                        0
                        • ? A Former User
                          31 Aug 2018, 08:28

                          @JonB: That is the problem i am facing. I do not know how to call setData which in turn emits the signal dataChanged. I do not know how to get the indexes. Here the data is only coming from the "Info_" variable. If the it was via delegates or adapters i could easily get the indexes and call setData. But in my case i get in a structure and go through each item and update its value. Could you please show me how can i achieve this in my code i.e. change the value via setData?

                          J Offline
                          J Offline
                          JonB
                          wrote on 31 Aug 2018, 08:50 last edited by
                          #25

                          @VInay123
                          Your code is way too big for me to wade through.

                          • If you are using QAbstractModel, you are using a model which holds data in rows & columns, right?

                          • When you put some data (received from JSON parsing or whatever), you have to decide where in the model's row/column you want to put this data, right?

                          • Given that row & column, you can construct a QModelIndex() (http://doc.qt.io/qt-5/qabstractitemmodel.html#createIndex) for the data.

                          • Then you can pass that to your Model::setData() to set the value, and emit dataChanged(index, index) to notify your view to update.

                          ? 1 Reply Last reply 31 Aug 2018, 09:08
                          1
                          • J JonB
                            31 Aug 2018, 08:50

                            @VInay123
                            Your code is way too big for me to wade through.

                            • If you are using QAbstractModel, you are using a model which holds data in rows & columns, right?

                            • When you put some data (received from JSON parsing or whatever), you have to decide where in the model's row/column you want to put this data, right?

                            • Given that row & column, you can construct a QModelIndex() (http://doc.qt.io/qt-5/qabstractitemmodel.html#createIndex) for the data.

                            • Then you can pass that to your Model::setData() to set the value, and emit dataChanged(index, index) to notify your view to update.

                            ? Offline
                            ? Offline
                            A Former User
                            wrote on 31 Aug 2018, 09:08 last edited by
                            #26

                            @JonB : Thank you. I implemented as following in my model:

                                QModelIndex index = createIndex(1, 1, categories_[0]->entryAt(0));
                                this->setData(index, 11, Qt::EditRole);
                            

                            It is changing the value clearly. But in the view its not being displayed.

                            J 1 Reply Last reply 31 Aug 2018, 09:34
                            0
                            • ? A Former User
                              31 Aug 2018, 09:08

                              @JonB : Thank you. I implemented as following in my model:

                                  QModelIndex index = createIndex(1, 1, categories_[0]->entryAt(0));
                                  this->setData(index, 11, Qt::EditRole);
                              

                              It is changing the value clearly. But in the view its not being displayed.

                              J Offline
                              J Offline
                              JonB
                              wrote on 31 Aug 2018, 09:34 last edited by
                              #27

                              @VInay123
                              Well at least we're getting somewhere! Check the return result of your setData(), maybe it's failing? Does (row, column) of (1, 1) exist in your model (else you need to insertRows() etc.)? Is that setData() call indeed going into your Model::setData() and doing the emit dataChanged() there (use a debugger or debug/print statements)? There's no point using both beginResetModel() & dataChanged(), and certainly not dataChanged() while still inside the beginResetModel() before the nedRestModel(). Change your code accordingly.

                              ? 1 Reply Last reply 31 Aug 2018, 10:38
                              1
                              • V Offline
                                V Offline
                                VRonin
                                wrote on 31 Aug 2018, 10:36 last edited by
                                #28

                                @VInay123 said in How to modify the data in the model and update the view when new data is received from external?:

                                CategoryItem& parentItem = currentItem->parentItem();
                                return createIndex(currentItem->row(), 0, &parentItem);

                                This is using the address of a temp item, it will not work.

                                QString data = file.readAll();

                                does not handle win/lunix line endings and encodings, use QString data = QTextStream(&file).readAll();


                                Use the model test to make sure your subclass works correctly

                                "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 31 Aug 2018, 10:54
                                2
                                • J JonB
                                  31 Aug 2018, 09:34

                                  @VInay123
                                  Well at least we're getting somewhere! Check the return result of your setData(), maybe it's failing? Does (row, column) of (1, 1) exist in your model (else you need to insertRows() etc.)? Is that setData() call indeed going into your Model::setData() and doing the emit dataChanged() there (use a debugger or debug/print statements)? There's no point using both beginResetModel() & dataChanged(), and certainly not dataChanged() while still inside the beginResetModel() before the nedRestModel(). Change your code accordingly.

                                  ? Offline
                                  ? Offline
                                  A Former User
                                  wrote on 31 Aug 2018, 10:38 last edited by A Former User
                                  #29

                                  @JonB: Yes, I just call the setData ane here i have printed the changed:

                                      if (role == Qt::EditRole && index.column() == 1 && index.isValid()) {
                                          auto currentItem = static_cast<ScenarioPropertyItem*>(index.internalPointer());
                                          if (currentItem) {
                                              currentItem->setValue(value);
                                              qDebug() << currentItem->data(index.column());
                                              emit dataChanged(index, index);
                                              return true;
                                          }
                                      }
                                  

                                  The value is being changed here. The output looks like

                                  QVariant(int, 11)
                                  

                                  I have included a debug output in Data() but this is printing the default values that is empty("").

                                  QVariantModel::data(const QModelIndex& index, int role /*= Qt::DisplayRole*/) const {
                                      if (!index.isValid()) {
                                          return QVariant();
                                      }
                                  
                                      if (role == Qt::DisplayRole && isCategory(index)) {
                                          const auto currentCategory = static_cast<CategoryItem*>(index.internalPointer());
                                          if (index.column() == 0) {
                                              return currentCategory->displayName();
                                          } else {
                                              return QVariant();
                                          }
                                      }
                                  
                                      const auto currentItem = static_cast<ScenarioPropertyItem*>(index.internalPointer());
                                      if (role == Qt::DisplayRole && !isCategory(index)) {
                                          qDebug() << currentItem->data(index.column()); // Here its empty
                                          return currentItem->data(index.column());
                                      }
                                      return QVariant();
                                  }
                                  
                                  
                                  J 1 Reply Last reply 31 Aug 2018, 10:51
                                  0
                                  • ? A Former User
                                    31 Aug 2018, 10:38

                                    @JonB: Yes, I just call the setData ane here i have printed the changed:

                                        if (role == Qt::EditRole && index.column() == 1 && index.isValid()) {
                                            auto currentItem = static_cast<ScenarioPropertyItem*>(index.internalPointer());
                                            if (currentItem) {
                                                currentItem->setValue(value);
                                                qDebug() << currentItem->data(index.column());
                                                emit dataChanged(index, index);
                                                return true;
                                            }
                                        }
                                    

                                    The value is being changed here. The output looks like

                                    QVariant(int, 11)
                                    

                                    I have included a debug output in Data() but this is printing the default values that is empty("").

                                    QVariantModel::data(const QModelIndex& index, int role /*= Qt::DisplayRole*/) const {
                                        if (!index.isValid()) {
                                            return QVariant();
                                        }
                                    
                                        if (role == Qt::DisplayRole && isCategory(index)) {
                                            const auto currentCategory = static_cast<CategoryItem*>(index.internalPointer());
                                            if (index.column() == 0) {
                                                return currentCategory->displayName();
                                            } else {
                                                return QVariant();
                                            }
                                        }
                                    
                                        const auto currentItem = static_cast<ScenarioPropertyItem*>(index.internalPointer());
                                        if (role == Qt::DisplayRole && !isCategory(index)) {
                                            qDebug() << currentItem->data(index.column()); // Here its empty
                                            return currentItem->data(index.column());
                                        }
                                        return QVariant();
                                    }
                                    
                                    
                                    J Offline
                                    J Offline
                                    JonB
                                    wrote on 31 Aug 2018, 10:51 last edited by
                                    #30

                                    @VInay123
                                    At this point I don't know any more. Maybe someone else does. We have described how things work. You might like to set up a tiny much simplified example to test how it all works, or look on the web for other examples and start from there.

                                    1 Reply Last reply
                                    0
                                    • V VRonin
                                      31 Aug 2018, 10:36

                                      @VInay123 said in How to modify the data in the model and update the view when new data is received from external?:

                                      CategoryItem& parentItem = currentItem->parentItem();
                                      return createIndex(currentItem->row(), 0, &parentItem);

                                      This is using the address of a temp item, it will not work.

                                      QString data = file.readAll();

                                      does not handle win/lunix line endings and encodings, use QString data = QTextStream(&file).readAll();


                                      Use the model test to make sure your subclass works correctly

                                      ? Offline
                                      ? Offline
                                      A Former User
                                      wrote on 31 Aug 2018, 10:54 last edited by
                                      #31

                                      @VRonin: With the test i got an error:

                                        // Common error test #2, make sure that a second level index has a parent
                                          // that is the first level index.
                                      

                                      What does above mean and how does it fit in my code?

                                      V 1 Reply Last reply 31 Aug 2018, 10:59
                                      0
                                      • ? A Former User
                                        31 Aug 2018, 10:54

                                        @VRonin: With the test i got an error:

                                          // Common error test #2, make sure that a second level index has a parent
                                            // that is the first level index.
                                        

                                        What does above mean and how does it fit in my code?

                                        V Offline
                                        V Offline
                                        VRonin
                                        wrote on 31 Aug 2018, 10:59 last edited by VRonin
                                        #32

                                        @VInay123 said in How to modify the data in the model and update the view when new data is received from external?:

                                        What does above mean and how does it fit in my code?

                                        It means that if model->hasChildren(parent) is true then index(0,0,parent).isValid() must be true and index(0,0,parent).parent()==parent.
                                        One of these 2 conditions is violated in your model.

                                        Again I strongly suggest you use QStandardItemModel rather than wasting time reimplementing your own

                                        "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 31 Aug 2018, 11:07
                                        5
                                        • V VRonin
                                          31 Aug 2018, 10:59

                                          @VInay123 said in How to modify the data in the model and update the view when new data is received from external?:

                                          What does above mean and how does it fit in my code?

                                          It means that if model->hasChildren(parent) is true then index(0,0,parent).isValid() must be true and index(0,0,parent).parent()==parent.
                                          One of these 2 conditions is violated in your model.

                                          Again I strongly suggest you use QStandardItemModel rather than wasting time reimplementing your own

                                          ? Offline
                                          ? Offline
                                          A Former User
                                          wrote on 31 Aug 2018, 11:07 last edited by A Former User
                                          #33

                                          @VRonin: My class looks good:

                                          QModelIndex Model::parent(const QModelIndex& index) const {
                                              if (!index.isValid()) {
                                                  return QModelIndex();
                                              }
                                          
                                              if (isCategory(index)) {
                                                  return QModelIndex();
                                              }
                                          
                                              const auto currentItem = static_cast<ScenarioPropertyItem*>(index.internalPointer());
                                              CategoryItem& parentItem = currentItem->parentItem();
                                          
                                              return createIndex(currentItem->row(), 0, &parentItem); // Here the row is always 1.. is it right??
                                          }
                                          
                                          int Model::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const {
                                              if (parent.column() > 0) {
                                                  return 0;
                                              }
                                          
                                              if (!parent.isValid()) {
                                                  return static_cast<int>(categories_.size());
                                              }
                                          
                                              if (isCategory(parent)) {
                                                  const auto currentCategory = static_cast<CategoryItem*>(parent.internalPointer());
                                                  return currentCategory->entryCount();
                                              }
                                          
                                              return 0;
                                          }
                                          
                                          int Model::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const {
                                              return 2;
                                          }
                                          

                                          0_1535713717270_Capture.PNG

                                          Coordinates are my categories and S, T are scenariopropertiesitem. Items has category as parents. Categories dont have parents.

                                          V 1 Reply Last reply 31 Aug 2018, 11:52
                                          0

                                          23/76

                                          31 Aug 2018, 08:26

                                          • Login

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