Sorting Numerical Values in QTableView with Widgets!
-
Hi,
We are using QTableView to create a table for our desktop application.
- Qt version : 5.9.7.
- We have to use QTableView. (Not QTableWidget)
- We have to use QStandardItemModel.
- We do not want to use QItemDelegate, if possible.
- We added checkboxes and pushbuttons into some columns using setIndexWidget() method.
- Table contains strings and numerical values but they are all represented with QStrings inside the QStandardItemModel.
We are trying to sort columns in the table with QStandardItemModel's sort() method; however, it sorts all of the values as strings as shown below.
The sorting is not correct. First value should be : 2.982 and the last value should be : 5623.902.
After that attempt, we have decided to use QSortFilterProxyModel. However, this time when we sort the table, the widgets such as checkboxes or pushbuttons are disappeared.
We think that checkboxes and pushbuttons are disappeared; because, they are not copyable.
Is there any method to sort the table correctly without causing checkboxes and pushbuttons to disappear?
-
@Oktay-K When using
setIndexWidget
, you should keep using one model as the view's model, don't change.
Actually, if you only want to sort the numbers properly and no further requirement on the display format, a simple way is that don't save the value in string.
For example, instead ofitem->setText("12.12");
using
item->setData(12.12, Qt::DisplayRole);
Then it will be sorted properly and there will be no need to use
QSortFilterProxyModel
.And if you have requirements on the display format / want to save a string to
Qt::DisplayRole
, you can also define a sort role.
Then save the value both in string and in numerical value.#define SORT_ROLE Qt::UserRole + 1 ... QStandardItem *item = new QStandardItem(); item->setText("12.12"); item->setData(12.12, SORT_ROLE); ... p_std_model->setSortRole(SORT_ROLE);
I think it is simpler than using a proxy model.
-
@Oktay-K Since you said you are using
QSortFilterProxyModel
for the view, I think at least you should use indexes ofQSortFilterProxyModel
, notQStandardItemModel
.
In your code,this
is the table view, right? How do you useQSortFilterProxyModel
then? -
@Bonnie
Yes,this
isQTableView
. We created a class namedSortModel
which inherits fromQSortFilterProxyModel
. We usedSortModel
as shown in the below.SortModel *p_model = new SortModel(this); QStandardItemModel * p_std_model = static_cast<QStandardItemModel*>(this->model()); if(Q_NULLPTR == p_model) return; if(Q_NULLPTR == p_std_model) return; p_model->setSourceModel(p_std_model); p_model->setSortRole(Qt::ItemDataRole::DisplayRole);
p_model->sort(column,Qt::AscendingOrder); QTableView::setModel(p_model);
We tried your suggestion and widgets are still disappering.
-
@Oktay-K When using
setIndexWidget
, you should keep using one model as the view's model, don't change.
Actually, if you only want to sort the numbers properly and no further requirement on the display format, a simple way is that don't save the value in string.
For example, instead ofitem->setText("12.12");
using
item->setData(12.12, Qt::DisplayRole);
Then it will be sorted properly and there will be no need to use
QSortFilterProxyModel
.And if you have requirements on the display format / want to save a string to
Qt::DisplayRole
, you can also define a sort role.
Then save the value both in string and in numerical value.#define SORT_ROLE Qt::UserRole + 1 ... QStandardItem *item = new QStandardItem(); item->setText("12.12"); item->setData(12.12, SORT_ROLE); ... p_std_model->setSortRole(SORT_ROLE);
I think it is simpler than using a proxy model.