How to use QStandardItemModel + QStandardItem sort two types data independent
-
Hi,I'm trying to write my own TreeWidget for inherite QStandardItemModel, and it will show data just list file and folder. I want to sort folder and file independently, just like:
raw data: @root |-- D file |-- C folder |-- B folder `-- A fileafter sort, i want to it look like
raw data: @root |-- A file |-- D file |-- B folder `-- C folderI try to write my own sort function refer to
QTreeWidget::sortItems, but it not works when i call itclass MyOwnTreeModel : public QStandardItemModel { void sortChilds(QStandardItem*pItems, Qt::SortOrder order); } void MyOwnTreeModel::sortChilds(QStandardItem*pItem, Qt::SortOrder order) { QVector<QPair<QStandardItem*, int> > sorting; for (int i = 0; i < pItem->rowCount(); i++) { /* get one type item, eg. all file or all folder */ } /* do sorting*/ QModelIndexList mFrom, mTo; for (int r = 0; r < sorting.count(); ++r) { int oldRow = sorting.at(r).second; if (oldRow == r) continue; QModelIndex from = createIndex(sorting[r].second, 0, sorting.at(r).first); /* it seems setChild not work */ pItem->setChild(sorting[r].second, 0, sorting.at(r).first); if (persistentIndexList().contains(from)) { QModelIndex to = createIndex(r, 0, sorting[r].first); mFrom.append(from); mTo.append(to); } } if (!mFrom.empty()) changePersistentIndexList(mFrom, mTo); }when i call
sortChildsin my own tree widget, just likeownModel->sortChilds(item), there is nothing happened.mToandFromshows the right order, it seemsQStandardItem::setChildnot work but i don't know why. -
EDIT: wrong code, see below
void MyOwnTreeModel::sortChilds(QStandardItem*pItem, Qt::SortOrder order) { if(!pItem) return; const int oldSortRole = sortRole(); setSortRole(Qt::UserRole); pItem->sortChildren(0,order); setSortRole(Qt::DisplayRole); pItem->sortChildren(0,order); setSortRole(oldSortRole); } -
EDIT: wrong code, see below
void MyOwnTreeModel::sortChilds(QStandardItem*pItem, Qt::SortOrder order) { if(!pItem) return; const int oldSortRole = sortRole(); setSortRole(Qt::UserRole); pItem->sortChildren(0,order); setSortRole(Qt::DisplayRole); pItem->sortChildren(0,order); setSortRole(oldSortRole); } -
@VRonin
Hmm. Cheaty!Does your code sort by
UserRoleand then byDisplayRole, is that why you write what you have? If so where does docs say that will work?? -
@JonB said in How to use QStandardItemModel + QStandardItem sort two types data independent:
Cheaty!
Indeed. The correct way would be to subclass
QStandardItemand reimplementoperator<but "aint nobody got time for that"@VRonin said in How to use QStandardItemModel + QStandardItem sort two types data independent:
The correct way would be to subclass QStandardItem and reimplement operator<
Which is what I would have done...
If yours works, where does
sortChildren()say anything about being a "stable" re-sort?? I don't get how/why it would work, if I understand you correctly.... -
@VRonin said in How to use QStandardItemModel + QStandardItem sort two types data independent:
The correct way would be to subclass QStandardItem and reimplement operator<
Which is what I would have done...
If yours works, where does
sortChildren()say anything about being a "stable" re-sort?? I don't get how/why it would work, if I understand you correctly....@JonB said in How to use QStandardItemModel + QStandardItem sort two types data independent:
where does sortChildren() say anything about being a "stable" re-sort??
It doesn't say it but that's what the code does: https://code.woboq.org/qt5/qtbase/src/gui/itemmodels/qstandarditemmodel.cpp.html#_ZN20QStandardItemPrivate12sortChildrenEiN2Qt9SortOrderE (uses
std::stable_sort) -
@JonB said in How to use QStandardItemModel + QStandardItem sort two types data independent:
where does sortChildren() say anything about being a "stable" re-sort??
It doesn't say it but that's what the code does: https://code.woboq.org/qt5/qtbase/src/gui/itemmodels/qstandarditemmodel.cpp.html#_ZN20QStandardItemPrivate12sortChildrenEiN2Qt9SortOrderE (uses
std::stable_sort)@VRonin
LOL, internals... :)But I still don't get it. Sorting by
UserRolefirst is to get directories separated from files, right (or wrong)? But then don't they both have aDisplayRolevalue for their name? In which case the second sort would not have any "stables" to retain from the first one, every item has its own name forDisplayRole, no? -
That's correct, I inverted the roles order, good catch!
void MyOwnTreeModel::sortChilds(QStandardItem*pItem, Qt::SortOrder order) { if(!pItem) return; const int oldSortRole = sortRole(); setSortRole(Qt::DisplayRole); pItem->sortChildren(0,order); setSortRole(Qt::UserRole); pItem->sortChildren(0,order); setSortRole(oldSortRole); } -
That's correct, I inverted the roles order, good catch!
void MyOwnTreeModel::sortChilds(QStandardItem*pItem, Qt::SortOrder order) { if(!pItem) return; const int oldSortRole = sortRole(); setSortRole(Qt::DisplayRole); pItem->sortChildren(0,order); setSortRole(Qt::UserRole); pItem->sortChildren(0,order); setSortRole(oldSortRole); }@VRonin
Ahhh, now that would make sense, with a stable second sort! Get them all alphabetical first, then separate as-is out into a directory versus file group.It's reassuring to learn that somebody else but me does not actually test the code they propose... ;-)