QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting
-
Hi
There are customized model derived from QAbstractTableModel class, customized proxyModel derived from QSortFilterProxyModel and TableView.
The question will be about sorting and consistency between model indexes and TableView indexes.
So if we set: ui->tableView.setSortingEnabled(true); and we click the header arrow of the tableView we can change the way of the sorting from Descending to Ascending also we
can edit a cell of the tableView and setData which trigger also sorting of the View.My question is : If the hereabove actions happen does the model indexes are consistent with the Tableview indexes. What is the preffered way to make them consistent?.
-
@Slawomir_Piernikowski said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
the model indexes are consistent with the Tableview indexes.
The view doesn't have indexes. When you sort on the view it does nothing but call
sort
on the model. If you have a custom way of sorting in your custom model you need to calllayoutAboutToBeChanged
/layoutChanged
to notify the view(s) that the order of items is changing. -
What happen if I do not have overloaded sort function in a customized model???
I have also customized QSortFilterProxyModel without overloaded sort function. -
This post is deleted!
-
Present state:
ui->tableView.setSortingEnabled(true);, the customized QAbstractTableModel do not have the sort function overloaded and the customised QSortFilterProxyModel also do not have the sort function overloaded.In this sate I still can sort. Is it ok????
I have found i Qt doc:
[virtual] void QSortFilterProxyModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
Reimplemented from QAbstractItemModel::sort().[virtual] void QAbstractItemModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
Sorts the model by column in the given order.
The base class implementation does nothing. -
@Slawomir_Piernikowski said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
In this sate I still can sort
Depends what is the model of
ui->tableView
. if it's the proxy model then sorting will work perfectly, if it's theQAbstractTableModel
subclass then it won't work -
So as I understand well having customized QSortFilterProxyModel even without overloaded sort function in the proxy do not prevent from sorting???
One condition is : ui->tableView.setSortingEnabled(true) -
@Slawomir_Piernikowski said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
having customized QSortFilterProxyModel even without overloaded sort function in the proxy do not prevent from sorting
Correct
One condition is : ui->tableView.setSortingEnabled(true)
It's not strictly necessary,
setSortingEnabled
is just one way of sorting -
You said that setSortingEnabled was just one way of sorting can You say more about it because if I set it to false it prevent from sorting. So it looks like "One condition is : ui->tableView.setSortingEnabled(true) " is obligatory if we want to sort???.
-
In Qt doc:
void QTableView::setSortingEnabled(bool enable)
If enable is true, enables sorting for the table and immediately trigger a call to sortByColumn() with the current sort section and order
Note: Setter function for property sortingEnabled.
See also isSortingEnabled().Now we look for: sortByColumn();
void QTableView::sortByColumn(int column, Qt::SortOrder order)
Sorts the model by the values in the given column in the given order.
This function was introduced in Qt 4.2.So indeed it is a one way of sorting a model.
Lets come back to:
You wrote: "the default implementation of QSortFilterProxyModel however, takes care of sorting perfectly fine"But it looks like it does not. I have checked it:
State:
ui->tableView.setSortingEnabled(false);
customized proxy model and customized model do not have overloaded sort functions.In qt doc is written that the sort function in QSortFilterProxyModel is derived from QAbstractItemModel class and the base class implementation does nothing.
[virtual] void QAbstractItemModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
Sorts the model by column in the given order.
The base class implementation does nothing.
So??? -
@Slawomir_Piernikowski said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
In qt doc is written that the sort function in QSortFilterProxyModel is derived from QAbstractItemModel class and the base class implementation does nothing.
But
QSortFilterProxyModel
reimplements it to do stuff.
It's easy to check the difference in code between QAbstractItemModel::sort and QSortFilterProxyModel::sort -
In Qt code:
void QAbstractItemModel::sort(int column, Qt::SortOrder order) { Q_UNUSED(column); Q_UNUSED(order); // do nothing }
void QSortFilterProxyModel::sort(int column, Qt::SortOrder order) { Q_D(QSortFilterProxyModel); if (d->dynamic_sortfilter && d->proxy_sort_column == column && d->sort_order == order) return; d->sort_order = order; d->proxy_sort_column = column; d->update_source_sort_column(); d->sort(); }
So as I see in the abowe code: if I have customized QSortFilterProxyModel the sort function is already overrided and do the sorting.... but
do You agree that if ui->tableView.setSortingEnabled(false); the sorting is not posible??? -
@Slawomir_Piernikowski said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
You agree that if ui->tableView.setSortingEnabled(false); the sorting is not posible???
No, I don't.
@VRonin said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
you are free to call ui->tableView->model()->sort(); wherever/whenever you want or even connect a signal to sort() of the model
-
So I decided to not use ui->tableView.setSortingEnabled(false) or ui->tableView.setSortingEnabled(true). I have customized proxy model and customized model which do not have overloaded sort functions.
I have tried to call setData function of the model(QAbstractTableModel) by clicking on a cell of the QTableView The data was changed but the model and view was not sorted ... so from the soft behaviour it looks like if you want to sort data from the level of the TableView it is obligatory to have set: ui->tableView.setSortingEnabled(true) or ui->tableView.setSortingEnabled(false) and use
sortByColumn function.
Am I right or I have missed something???
Maybe this will be helpful:void QTableView::sortByColumn(int column, Qt::SortOrder order) { Q_D(QTableView); if (column < 0) return; // If sorting is enabled it will emit a signal connected to // _q_sortIndicatorChanged, which then actually sorts d->horizontalHeader->setSortIndicator(column, order); // If sorting is not enabled, force to sort now if (!d->sortingEnabled) d->model->sort(column, order); }
If sotring is not enabled, force to sort now???
So even if ui->tableView.setSortingEnabled(false) and we call sortByColumn the model will be sorted.
I asked:
You agree that if ui->tableView.setSortingEnabled(false); the sorting is not posible???
You answered:
No, I don't.
Yes You were right even if ui->tableView.setSortingEnabled(false) we can still sort a model using
sortByColumn function.But if ui->tableView.setSortingEnabled(false) which is by default and we do not use sortByColumn function in my soft sorting not works when I set data of a cell of the tableView.
-
@VRonin said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
you are free to call ui->tableView->model()->sort();
Yes of course it can be done.
I just add in:bool MagazynModel::setData(const QModelIndex &index, const QVariant &value, int role) { .... this->sort(index.column()); }
and now when I set data in the tableView sorting is working.
-
@Slawomir_Piernikowski said in QTableView, QAbstractTableModel, QSortFilterProxyModel, Sorting:
when I set data of a cell of the tableView.
This was they key piece of information you left out in your previous posts. You want automatic sorting when data changes. In that case setting
ui->tableView->setSortingEnabled(true);
is the most convenient way, alternatively you canQObject::connect(ui->tableView->model(),&QAbstractItemModel::dataChanged,ui->tableView->model(),&QAbstractItemModel::sort,Qt::QueuedConnection);
P.S.
sortByColumn
has been deprecated, it should not be used in any new code -
QObject::connect(ui->tableView->model(),&QAbstractItemModel::dataChanged,ui->tableView->model(),&QAbstractItemModel::sort,Qt::QueuedConnection);
This is not the place for detailed discussion, but in a word why do you specify
Qt::QueuedConnection
here, please?