Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved Sorting Numerical Values in QTableView with Widgets!

    General and Desktop
    2
    7
    2910
    Loading More Posts
    • 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
      Oktay K. last edited by

      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 Reply Quote 1
      • B
        Bonnie @Oktay K. last edited by Bonnie

        @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 Reply Quote 3
        • B
          Bonnie last edited by Bonnie

          Hi, did you call setIndexWidget with a mapped index?

          O 1 Reply Last reply Reply Quote 0
          • O
            Oktay K. @Bonnie last edited by

            @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 Reply Quote 0
            • B
              Bonnie @Oktay K. last edited by 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 1 Reply Last reply Reply Quote 0
              • O
                Oktay K. @Bonnie last edited by 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 1 Reply Last reply Reply Quote 0
                • B
                  Bonnie @Oktay K. last edited by Bonnie

                  @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 Reply Quote 3
                  • O
                    Oktay K. last edited by

                    @Bonnie

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

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post