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 file
after sort, i want to it look like
raw data: @root |-- A file |-- D file |-- B folder `-- C folder
I 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
sortChilds
in my own tree widget, just likeownModel->sortChilds(item)
, there is nothing happened.mTo
andFrom
shows the right order, it seemsQStandardItem::setChild
not 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
UserRole
and 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
QStandardItem
and 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
UserRole
first is to get directories separated from files, right (or wrong)? But then don't they both have aDisplayRole
value 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... ;-)