Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Sorting Numerical Values in QTableView with Widgets!
Forum Update on Monday, May 27th 2025

Sorting Numerical Values in QTableView with Widgets!

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 5.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    Oktay K.
    wrote on last edited by
    #1

    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.

    Sorted.png

    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.

    SortedQProxy.png

    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?

    1 Reply Last reply
    1
    • O Oktay K.

      @Bonnie
      Yes, this is QTableView. We created a class named SortModel which inherits from QSortFilterProxyModel. We used SortModel 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.

      B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #6

      @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 of

      item->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.

      1 Reply Last reply
      3
      • B Offline
        B Offline
        Bonnie
        wrote on last edited by Bonnie
        #2

        Hi, did you call setIndexWidget with a mapped index?

        O 1 Reply Last reply
        0
        • B Bonnie

          Hi, did you call setIndexWidget with a mapped index?

          O Offline
          O Offline
          Oktay K.
          wrote on last edited by
          #3

          @Bonnie

          QStandardItemModel *p_model = static_cast<QStandardItemModel *> (this->model());
          QCheckBox *p_check_box = new QCheckBox();
          setIndexWidget(p_model->index(row,in_column_pos), p_check_box);
          
          B 1 Reply Last reply
          0
          • O Oktay K.

            @Bonnie

            QStandardItemModel *p_model = static_cast<QStandardItemModel *> (this->model());
            QCheckBox *p_check_box = new QCheckBox();
            setIndexWidget(p_model->index(row,in_column_pos), p_check_box);
            
            B Offline
            B Offline
            Bonnie
            wrote on last edited by Bonnie
            #4

            @Oktay-K Since you said you are using QSortFilterProxyModel for the view, I think at least you should use indexes of QSortFilterProxyModel, not QStandardItemModel .
            In your code, this is the table view, right? How do you use QSortFilterProxyModel then?

            O 1 Reply Last reply
            0
            • B Bonnie

              @Oktay-K Since you said you are using QSortFilterProxyModel for the view, I think at least you should use indexes of QSortFilterProxyModel, not QStandardItemModel .
              In your code, this is the table view, right? How do you use QSortFilterProxyModel then?

              O Offline
              O Offline
              Oktay K.
              wrote on last edited by Oktay K.
              #5

              @Bonnie
              Yes, this is QTableView. We created a class named SortModel which inherits from QSortFilterProxyModel. We used SortModel 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.

              B 1 Reply Last reply
              0
              • O Oktay K.

                @Bonnie
                Yes, this is QTableView. We created a class named SortModel which inherits from QSortFilterProxyModel. We used SortModel 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.

                B Offline
                B Offline
                Bonnie
                wrote on last edited by Bonnie
                #6

                @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 of

                item->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.

                1 Reply Last reply
                3
                • O Offline
                  O Offline
                  Oktay K.
                  wrote on last edited by
                  #7

                  @Bonnie

                  It works. Thank you for everything. Have a great day.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved