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. TreeView not updating after a dataChanged signal
Qt 6.11 is out! See what's new in the release blog

TreeView not updating after a dataChanged signal

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 5 Posters 2.4k 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.
  • SGaistS SGaist

    Hi,

    One thing you can do is use the QAbstractItemModelTester class to check that your implementation works as expected.

    C Offline
    C Offline
    Coubz
    wrote on last edited by Coubz
    #3

    @SGaist Yep I've tryed that already.
    It shown me some issues that i've corrected but the datachanged(...) still doesn't do anything.
    One noticeable fix was to return an invalid QModelIndex with the parent method when the parent is the root node of the tree.
    Is there a way to be able to break in the TreeView code to follow the signal reception an see what's wrong?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Coubz
      wrote on last edited by
      #4

      Is it possible that i miss something to set the TreeView as "dirty" ?
      The TreeView or an other Qml element that contains it, or the items inside the view maybe.
      It's weird because as i said if i drag the view to move the text of the items outside of the windows thay will update.

      Currently the hierarchy is something like that :

      ApplicationWindow
          Rectangle
              GridLayout
                  Item
                      ColumnLayout
                          Item
                              Rectangle
                                  TreeView
                                      TreeViewDelegate
                                          Row
                                              CheckBox
                                              Text
      
      Christian EhrlicherC JonBJ 2 Replies Last reply
      0
      • C Coubz

        Is it possible that i miss something to set the TreeView as "dirty" ?
        The TreeView or an other Qml element that contains it, or the items inside the view maybe.
        It's weird because as i said if i drag the view to move the text of the items outside of the windows thay will update.

        Currently the hierarchy is something like that :

        ApplicationWindow
            Rectangle
                GridLayout
                    Item
                        ColumnLayout
                            Item
                                Rectangle
                                    TreeView
                                        TreeViewDelegate
                                            Row
                                                CheckBox
                                                Text
        
        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #5

        Your dataChanged() is wrong somehow. Minimize your code, remove qml and use a simple QTreeView until you can either reproduce it in a minimal compilable example or find your bug. The models work correct and don't need a special update except dataChanged() when some data changes inside the model.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        1
        • C Coubz

          Is it possible that i miss something to set the TreeView as "dirty" ?
          The TreeView or an other Qml element that contains it, or the items inside the view maybe.
          It's weird because as i said if i drag the view to move the text of the items outside of the windows thay will update.

          Currently the hierarchy is something like that :

          ApplicationWindow
              Rectangle
                  GridLayout
                      Item
                          ColumnLayout
                              Item
                                  Rectangle
                                      TreeView
                                          TreeViewDelegate
                                              Row
                                                  CheckBox
                                                  Text
          
          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #6

          @Coubz
          I agree with @Christian-Ehrlicher. I would suspect the dataChanged() signal itself is fine and being acted on, but somehow the indexes are not what you think they are so it does not redraw the right thing?

          1 Reply Last reply
          0
          • C Offline
            C Offline
            Coubz
            wrote on last edited by Coubz
            #7

            I've managed to make it work, i'm not exactly sure to understand why tho.
            I had to change the way the setData reacts :

            bool MapMarkerTreeModel::setData(const QModelIndex& _index, const QVariant& _value, int _role/* = Qt::EditRole*/)
            {
                if (!_index.isValid())
                {
                    return false;
                }
            
                if(MapMarkerTreeItem* item = getItem(_index))
                {
                    if(item->setData(_value, _role))
                    {
                        //emit dataChanged(_index, _index); // <-----  Previous version
            
                        QList<int> roles{Qt::DisplayRole, Qt::EditRole, _role};
                        QModelIndex id = createIndex(_index.row(), item->getColumnIdFromRole(_role), item);
                        emit dataChanged(id, id, roles);
                        return true;
                    }
                }
            
                return false;
            }
            

            So it seems that the dataChanged signals have to build the role into the column of the ID else it won't refresh properly.
            I thought the role param of the signal would be able to do the trick but i think there is something i didn't understood here.

            JonBJ SGaistS 2 Replies Last reply
            0
            • C Coubz

              I've managed to make it work, i'm not exactly sure to understand why tho.
              I had to change the way the setData reacts :

              bool MapMarkerTreeModel::setData(const QModelIndex& _index, const QVariant& _value, int _role/* = Qt::EditRole*/)
              {
                  if (!_index.isValid())
                  {
                      return false;
                  }
              
                  if(MapMarkerTreeItem* item = getItem(_index))
                  {
                      if(item->setData(_value, _role))
                      {
                          //emit dataChanged(_index, _index); // <-----  Previous version
              
                          QList<int> roles{Qt::DisplayRole, Qt::EditRole, _role};
                          QModelIndex id = createIndex(_index.row(), item->getColumnIdFromRole(_role), item);
                          emit dataChanged(id, id, roles);
                          return true;
                      }
                  }
              
                  return false;
              }
              

              So it seems that the dataChanged signals have to build the role into the column of the ID else it won't refresh properly.
              I thought the role param of the signal would be able to do the trick but i think there is something i didn't understood here.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by JonB
              #8

              @Coubz
              You posted this topic in General and Desktop rather than https://forum.qt.io/category/12/qml-and-qt-quick. I assumed you were talking about a Qt widgets QTreeView. Are you in fact using QML and its TreeView? You never mentioned QML....

              1 Reply Last reply
              0
              • C Coubz

                I've managed to make it work, i'm not exactly sure to understand why tho.
                I had to change the way the setData reacts :

                bool MapMarkerTreeModel::setData(const QModelIndex& _index, const QVariant& _value, int _role/* = Qt::EditRole*/)
                {
                    if (!_index.isValid())
                    {
                        return false;
                    }
                
                    if(MapMarkerTreeItem* item = getItem(_index))
                    {
                        if(item->setData(_value, _role))
                        {
                            //emit dataChanged(_index, _index); // <-----  Previous version
                
                            QList<int> roles{Qt::DisplayRole, Qt::EditRole, _role};
                            QModelIndex id = createIndex(_index.row(), item->getColumnIdFromRole(_role), item);
                            emit dataChanged(id, id, roles);
                            return true;
                        }
                    }
                
                    return false;
                }
                

                So it seems that the dataChanged signals have to build the role into the column of the ID else it won't refresh properly.
                I thought the role param of the signal would be able to do the trick but i think there is something i didn't understood here.

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #9

                @Coubz well, once you mention using QML it starts to make sense.

                QML uses custom roles to access data hence if you don't tell dataChanged that the data corresponding to these roles has changed, then there's no reason for the view to update.

                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
                1
                • C Offline
                  C Offline
                  Coubz
                  wrote on last edited by
                  #10

                  Yes i do use QML sorry.
                  So what you're saying is that if you use QML the roles handled on the code side are irrelevant ?
                  It seems a bit weird as if a edit a values at runtime i do get the proper role in the setData callback.
                  It just that i've neglected the column of the index because i was thinking that the view won't be needing it as it had the role. And because the setData callback have an index without the column setup when trigged by edition.

                  SGaistS 1 Reply Last reply
                  0
                  • C Coubz

                    Yes i do use QML sorry.
                    So what you're saying is that if you use QML the roles handled on the code side are irrelevant ?
                    It seems a bit weird as if a edit a values at runtime i do get the proper role in the setData callback.
                    It just that i've neglected the column of the index because i was thinking that the view won't be needing it as it had the role. And because the setData callback have an index without the column setup when trigged by edition.

                    SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #11

                    Quite the contrary, proper role handling is paramount to have a correctly working model view implementation.

                    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
                    0
                    • C Coubz has marked this topic as solved on
                    • O Offline
                      O Offline
                      Oleksii_S
                      wrote last edited by
                      #12

                      Just want to share some debugging tips for the issue:
                      Step 1: Put the debug output inside data method of your implementation the QAbstractItemModel class, like

                      QVariant TestViewModel::data(const QModelIndex &index, int role) const
                      {
                              qDebug() << "data" << index.row() << index.column() << role;
                              ...
                      }
                      

                      Then make sure you are updating the cell with same index adding the same output before emiting dataChanged signal.

                      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