TreeView not updating after a dataChanged signal
- 
Everything is in the title, i have a treeview displaying a custom model. 
 I'm trying to edit some data in it but the dataChanged signal doesn't seems to work.I've tried with the begin/endResetModel which is working fine. 
 I also noticed that the edited field is updating if I hide it thew reshow it by dragging the treeview out of the layer (as the content of the treeview draggable).I've also tried to send the signal on the root or on the parents. 
 Things like that :QModelIndex rootIndex = createIndex(0, 0, m_root); QModelIndex rootIndex2 = createIndex(m_root->childCount(), m_root->columnCount(), m_root); emit dataChanged(rootIndex, rootIndex2);but with no results. I'm pretty sure there is some subtilty i didn't get but i can't find out so i need your help =) Here's a simplified version of what i'm doing : 
 -In my tree model :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)) { // beginResetModel(); <----- This is working // endResetModel(); emit dataChanged(_index, _index); // <----- This isn't return true; } } return false; }-Also in my tree model, index and parent methods : QModelIndex MapMarkerTreeModel::index(const MapMarkerTreeItem* _item) const { QModelIndex index{}; if(_item != nullptr) { index = createIndex(_item->childNumber(), 0, _item); } return index; } QModelIndex MapMarkerTreeModel::parent(const QModelIndex& _index) const { if (!_index.isValid() || m_root == nullptr) { return QModelIndex(); } MapMarkerTreeItem* childItem = getItem(_index); MapMarkerTreeItem* parentItem = childItem ? childItem->parent() : nullptr; if (!parentItem) { return QModelIndex(); } return createIndex(parentItem->childNumber(), 0, parentItem); }I'm not sure what else I can provide for context, if anything can help please tell me. 
 And thanks in advance !
- 
Hi, One thing you can do is use the QAbstractItemModelTester class to check that your implementation works as expected. 
- 
Hi, One thing you can do is use the QAbstractItemModelTester class to check that your implementation works as expected. @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?
- 
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
- 
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 TextYour 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. 
- 
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
- 
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.
- 
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.
- 
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.@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. 
- 
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.
- 
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.Quite the contrary, proper role handling is paramount to have a correctly working model view implementation. 
- 
C Coubz has marked this topic as solved on
 

