[SOLVED] QPersistentModelIndex usage
-
I think so:
@emit layoutAboutToBeChanged();
qSort(childItems.begin(), childItems.end(), compareFilenameA);
emit layoutChanged();@ -
try "QAbstractItemModel::dataChanged()":http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#dataChanged
If it doesn't make a difference you can also try "QAbstractItemModel::changePersistentIndex()":http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#changePersistentIndex -
Same result. My model is sorted correctly but QPersistenModelIndex.row() has old value. Don't know if it's ok
-
before further investigating i would recommend that you try "ModelTest":http://qt-project.org/wiki/Model_Test to make sure your model is implemented correctly.
-
Ehh, can't adjust ModelTest to my model. There are really missing example of QPersistentModelIndex usage. Summarizing, my model is working ok, but don't know why :P . I have this structure:
@struct HCFileItem {
QPersistentModelIndex persistentIndex;
};class HCFileModel: public QAbstractItemModel
{
Q_OBJECT
public:
explicit HCFileModel(QObject parent=0);
~HCFileModel();
protected:
QList<HCFileItem> *mList=0;
};@Example:
My model contain one item:
"bbbb"
Now I'm inserting (using beginInsertRows) item "aaaa" and my persistent indexes looks like:
"bbbb" (0,0)
"aaaa" (1,0)Now I'm sorting my model using qSort on mList and emitting signal dataChanged(firstIndex, secondIndex). After this my persistent indexes looks like:
"aaaa" (1,0)
"bbbb" (0,0)But it works, if I change data in "aaaa" and emit signal dataChanged with saved persistent index in HCFileItem then correct item is refreshed even if QPersistentModelIndex.row() point to wrong row. I'm confused
-
using ModelTest is as easy (nothing to adjust at all) as:
@
HCFileModel* model = new HCFileModel(parent);
new ModelTest(model, parent);
@
If your model has an error in any state while you use it an assertion will trigger and give you info what went wrong. -
Ok my model pass test. So I have no idea why QPersistentModelIndex row() has old value after sort. But everything work, IsValid return True. Must check on QStandardItemModel and QSortFilterProxyModel if persistent index will keep old row too
-
Maybe should I somehow refresh all persistent indexes after sorting?
-
I did some dirty test. Instead of qSort(), I'm moving new added item manually to destination row by:
@beginMoveRows(parent->index, 4, 4, parent->index, 0);
parent->childItems.move(4,0); // this is QList
endMoveRows();@
... and now all persistent indexes are updated automatically. So I suppose that I need to do something with persistent indexes after qSort() call. Or just call modelreset (I don't know which items changed after sort anyway) and create new persistent indexes for all items. changePersistentIndex doesn't change anything
And another question: where QPersistentModelIndex should be created? Now I'm creating it from "outside" model class (after childItems.append()) but maybe should I do this in QAbstractItemModel.createIndex() ? -
[quote author="Kobid" date="1383942370"]
And another question: where QPersistentModelIndex should be created? Now I'm creating it from "outside" model class (after childItems.append()) but maybe should I do this in QAbstractItemModel.createIndex() ?[/quote]
Since QpersistenModelIndex are a bit of an overhead i would only create them when needed. Thus outside of the model is fine, thats what they are actually for. THe modle should only create QModelIndex objects. -
Problem solved! I looked what QStandardItemModel do in sort method and I used similar algorithm. So here is complete solution if someone have same problem (note that my childs are based on QVectior, if you are using QList then you need to modify it a little):
@void HCDirModel::sortChilds(HCDirItem *p)
{
if (p->childCount()==0) return;QVector<QPair<HCDirItem*, int> > l(p->childItems.count()); for (int i=0; i < p->childItems.count(); ++i) { l[i] = QPair<HCDirItem*,int>(p->childItems[i], i); } qStableSort(l.begin(), l.end(), compareFilenameA); QModelIndexList mFrom, mTo; for (int i = 0; i < l.count(); ++i) { p->childItems[i] = l[i].first; QModelIndex from = createIndex(l[i].second, 0, l[i].first); if (persistentIndexList().contains(from)) { QModelIndex to = createIndex(i, 0, l[i].first); mFrom.append(from); mTo.append(to); } } if (!mFrom.empty()) changePersistentIndexList(mFrom,mTo);
}@
And usage:
@emit layoutAboutToBeChanged();
sortChilds(it);
emit layoutChanged();@