[Solved] Sorting QML Tableview is slow
-
Hello folks,
we have implemented a sortable table in QML. Sorting takes a long time, I haven't measured exactly, but it is approximately a minute for about 8000 rows. I've ran the test through a profiler and according to that, within the
QSortFilterProxyModel::sort()
function, most of the time (>99%) is spent inQAbstractItemModel::LayoutChanged()
and subsequent calls. We emit thelayoutChanged()
only after sorting has completed. So this is puzzling me quite a bit. So my question is: Is this signal emitted internally during the sort function? If yes, are these sort times normal for a QML table?void MySortFilterProxyModel::setSortOrder(Qt::SortOrder order) { QAbstractItemModel* src = qobject_cast<QAbstractItemModel*>(source()); emit src->layoutAboutToBeChanged(); QSortFilterProxyModel::sort(0, order); emit src->layoutChanged(); }
I read various threads and questions on the topic, but none of them seems to match our setup with using a QML tableview and they usually somewhere emit the
layoutChanged()
which makes them slow.On demand I could post complete sources but I do not think they are at fault here.
-
Results of profiling after
sort()
to show that none of our custom functions is involved..I've inspected the all of the tree and there is no more of our code involved, only Qt internals.99,78 QSortFilterProxyModel::sort
99,78 ----QSortFilterProxyModelPrivate::sort
99,78 --------QAbstractItemModel::layoutChanged
99,78 ------------QMetaObject::activate
99,78 ----------------QMetaObject::activate
99,78 --------------------QMetaObject::metacall
99,78 ------------------------QQmlDelegateModel::qt_metacall
99,78 -----------------------------QQmlDelegateModel::qt_static_metacall
99,78 ---------------------------------QQmlDelegateModel::_q_layoutChanged
99,7 ---------------------------------------QQmlDelegateModel::_q_itemsMoved
0,01 ---------------------------------------QList<QQmlDelegateModelItem *>::at
0,01 ---------------------------------------QQmlDelegateModelItem::modelIndex
0,01 ---------------------------------------QQmlDelegateModelItem::setModelIndex
0,00 ---------------------------------------QQmlDelegateModelPrivate::itemsMoved
0,00 ---------------------------------------QPersistentModelIndex::row
0,00 ---------------------------------------QVectorQQmlListCompositor::Insert::~QVectorQQmlListCompositor::Insert
0,00 ---------------------------------------@ILT+10530(?setModelIndex@QQmlDelegateModelItem@@QAEXH@Z)
0,00 ---------------------------------------QQmlListCompositor::listItemsMoved -
I am pretty sure the QSortFilterProxy tries to move the items in the model so that they can be animated. I think you might be better off with just resetting the entire model if you have a lot of items. I will say that you would think it wouldn't need to move items outside of the view, but idk how qml implements a tableview. You would call QAbstractItemModel::modelReset(). I guess you could try to slap it into a C++ table view and see if the same behavior is observed.
-
Hi eagain!
I think Buttink is right. I suggest to add a boolean property to your model in C++ that is true only during sorting. Then you could use this property to detach the model from the view during sorting in QML like this:
MyTableView {
model: myModel.isSorting ? null : myModel
}Cheers!
Wieland -
@eagain said:
@p3c0 I tried, but apparently im too blind to find that button. The "Topic Tools" only contain the option to "Delete Topic"
At the moment, only moderators can mark topics as solved: http://forum.qt.io/topic/51926/real-quick-forum-things/4 Tero, our community manager, is looking to give every user that ability.
In the meantime, I believe you can mark it by editing the original post and adding "[Solved]" to the start of the title.