Important: Please read the Qt Code of Conduct -

Sorting is wrong when using QSortFilterProxyModel on number strings and getting wrong column text

  • Hello all
    i have simple model view treeview with QSortFilterProxyModel proxy to sort the columns and QStandardItemModel as the model
    in each columns there are string that gets sorted fine but in columns that contains number ( as strings ) the sorting wrong .
    say i have 9,12,1 (each number in different column when i sort them im getting 1,12,9 or 12,1,9 but never in the right order .
    like 1,9,12 or 12,9,1 why ?
    also i notice that when i sort row by column , when i try to get the new column text with m_model->item(iSelectedRow,0)->text();
    im getting the initial column text but never the new sorted column text. why ?

  • String comparisons for numbers are done in the same way as they are done for other text. Text will always be sorted as "a, after, and", so you might just get lists like "1, 123, 13" when using numbers. If you are passing integers, just pass the numbers from your model. They'll be converted to string automatically where necessary.

  • i dont understand how can i pass the strings as numbers to the sorting filter ?

  • I remember having the same problem. At the time, the only solution I could come up with that worked was to subclass QSortFilterProxyModel, and provide my own definition of when an item was "larger than" another item.

    But if you can make the sorting use numbers instead of strings, as Franzk suggests, that should work too. But then you probably have to store the numbers as numbers in the model, not as strings.

  • i dont have problem to store it as number its even better , but how ?
    do you mean in
    @them_model->item(iSelectedRow,0)->setData(..value .., which role? )@
    if yes which role should i use ?

  • Have you considered writing your own custom Item model? Or at least a custom QStandardItem subclass.

    From the doc of QStandardItem :
    @Reimplement data() and setData() if you want to perform custom handling of data queries and/or control how an item's data is represented.@

  • There is a SortRole property in the latest snapshot:
    This feature makes implementing your requirement very easy.

  • is there any tutorial ? how can i use it ?

  • define a sort role:
    @const int sortRole = Qt::UserRole +1;@

    QStandardItemModel lets you save custom values with setData and role = sortRole. For every column you can decide whether you want to hold QString or int.

    Tell the sort method what role to use for sorting: @myStandardItemModel.setSortRole(sortRole);@

    Now sorting works based on the values you have saved in every cell with sortRole.

  • Hi all
    well thanks for the answer . it working .
    for the secound question i found the solution and it looks like this :
    @QString groupID = index.model()->index(index.row(), 0, index.parent()).data(Qt::UserRole).toString();
    QString groupName = index.model()->index(index.row(), 0, index.parent()).data(Qt::DataRole).toString();@

    but there is one more problem is how do i setData to column in index ( for example 3 ) in the selected row
    this dosn't work :
    @index.model()->index(index.row(), 3, index.parent()).setData(.......)@

  • You get a QModelIndex for the current cell via this method
    @QModelIndex QAbstractItemView::currentIndex () @
    If you really want the selected cells and not the current cell you can query the selection Model, which is available via the view.
    Once you have the QModelIndex of the target cell you can call the models setData() method with it.

  • well this is the thing that i dont have the index of the cell i want to change only the row .

  • The row is not enough, because you have a tree and the hierarchy is also needed.
    You need to have a QModelIndex of a cell which is close to where you want to go.
    If you have a QModelIndex of the parent item you can use
    @QModelIndex::child ( int row, int column ) @
    If you have a QModelIndex of a sibling, for example an item in the same row you would use
    @QModelIndex::sibling ( int row, int column ) @

Log in to reply