Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to sort in TableView like QTableView?
QtWS25 Last Chance

How to sort in TableView like QTableView?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
14 Posts 3 Posters 2.6k 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.
  • J Offline
    J Offline
    JohnDaYe
    wrote on last edited by JohnDaYe
    #1

    i select a row like this
    0_1538729321071_1.jpg
    it will display after sort like this
    0_1538729392263_2.jpg

    how to let table view select the same data after a sort?

    mymodel

    //Header
    #ifndef TABLEVIEWMODEL_H
    #define TABLEVIEWMODEL_H
    
    #include <QAbstractTableModel>
    
    struct TableViewItem {
        int     iNumber;
        QString strName;
    };
    
    class TableViewModel
            : public QAbstractTableModel
    {
        Q_OBJECT
        Q_PROPERTY(QString sortRole READ sortRole WRITE setSortRole)
    public:
        enum {Role_Number = Qt::UserRole + 1, Role_Name};
        TableViewModel(QObject *parent);
        virtual ~TableViewModel() override;
    
        // QAbstractItemModel interface
    public:
        int rowCount(const QModelIndex &parent) const override;
        int columnCount(const QModelIndex &parent) const override;
        QVariant data(const QModelIndex &index, int role) const override;
        QString sortRole() const;
        void setSortRole(QString sortRole);
        // QAbstractItemModel interface
    public:
        QHash<int, QByteArray> roleNames() const override;
    protected:
        int sortKey(const QString &name) const;
    protected:
        QVector<TableViewItem> mData;
        QString mSortRole;
    };
    
    #endif // TABLEVIEWMODEL_H
    
    //CPP
    #include "tableviewmodel.h"
    #include <algorithm>
    #include <QDebug>
    #include <QMap>
    TableViewModel::TableViewModel(QObject *parent)
        : QAbstractTableModel(parent)
    {
        mData.push_back({1, "Candy"});
        mData.push_back({2, "John"});
    }
    
    TableViewModel::~TableViewModel()
    {
    
    }
    
    
    int TableViewModel::rowCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return mData.size();
    }
    
    int TableViewModel::columnCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return 2;
    }
    
    QVariant TableViewModel::data(const QModelIndex &index, int role) const
    {
        if(!hasIndex(index.row(), index.column()))
            return QVariant();
        switch (role)
        {
            case Role_Number:
                return mData[index.row()].iNumber;
            case Role_Name:
                return mData[index.row()].strName;
        }
        return QVariant();
    }
    
    QHash<int, QByteArray> TableViewModel::roleNames() const
    {
        QHash<int, QByteArray> roleName;
        roleName[Role_Number] = "number";
        roleName[Role_Name] = "name";
        return roleName;
    }
    
    QString TableViewModel::sortRole() const
    {
        return mSortRole;
    }
    
    void TableViewModel::setSortRole(QString sortRole)
    {
        mSortRole = sortRole;
    
        QVector<QPair<TableViewItem,int>> sortable;
        for (int row = 0; row < rowCount(QModelIndex()); ++row) {
            sortable.append({mData[row], row});
        }
    
        beginResetModel();
        int role = sortKey(mSortRole);
        switch (role)
        {
            case Role_Name:
            {
                std::stable_sort(mData.begin(), mData.end(), [](const TableViewItem &rhs, const TableViewItem &lhs){
                   return lhs.strName < rhs.strName;
                });
            }
            break;
            case Role_Number:
            {
                std::stable_sort(mData.begin(), mData.end(), [](const TableViewItem rhs, const TableViewItem& lhs){
                   return lhs.iNumber < rhs.iNumber;
                });
            }
            break;
        }
        endResetModel();
    }
    
    int TableViewModel::sortKey(const QString &name) const
    {
        auto roleName = roleNames();
        for(auto it = roleName.begin(); it != roleName.end(); ++it)
        {
            if(it.value() == name)
                return it.key();
        }
        return -1;
    }
    //QML
    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.4 as Ctrl14
    import QtQuick.Controls 2.4
    import QtQuick.Controls.Styles 1.4
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        Ctrl14.TableView {
            x: 34
            y: 64
            width: 349
            height: 343
            id: tableView
            sortIndicatorVisible: true
            objectName: "tableView"
            selectionMode: Ctrl14.SelectionMode.ExtendedSelection
            Ctrl14.TableViewColumn {
                role: "number"
                title: "No."
            }
            Ctrl14.TableViewColumn {
                role: "name"
                title: "Name"
            }
            onSortIndicatorColumnChanged: {
                model.sortRole = tableView.getColumn(tableView.sortIndicatorColumn).role
            }
        }
    
        Button {
            id: button
            x: 397
            y: 378
            width: 74
            height: 29
            text: qsTr("Button")
        }
    }
    
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What version of Qt ?
      On what OS ?
      What type of model ?
      How do you implement the sorting ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • J Offline
        J Offline
        JohnDaYe
        wrote on last edited by
        #3

        Qt 5.11.2
        Windows 10 64Bit
        I already paste the code , thanks!

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          What happens if rather than the begin/endResetModel, you just call dataChanged ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          J 1 Reply Last reply
          0
          • SGaistS SGaist

            What happens if rather than the begin/endResetModel, you just call dataChanged ?

            J Offline
            J Offline
            JohnDaYe
            wrote on last edited by
            #5

            @SGaist
            I think, I don't need to call dataChanged

            JonBJ 1 Reply Last reply
            0
            • J JohnDaYe

              @SGaist
              I think, I don't need to call dataChanged

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by JonB
              #6

              @JohnDaYe

              I think, I don't need to call dataChanged

              ?

              My advice would be: if @SGaist suggests you try something you heed it!

              When you call beginResetModel Qt throws away all existing information about the model, including which row was selected. The view presumably then just remembers row #2 was selected and reselects that.

              If instead you call dataChanged on each index it may remember which row in the model was selected and re-select the model row, not the view row number.

              Otherwise, if that does not work or you wish to stick beginResetModel, before you sort you should store which row is selected by its content. That is usually the primary key, which looks like it might be your iNumber? Then after the sort you go find that row again by its content and reselect that. Any problem with that?

              J 1 Reply Last reply
              0
              • J Offline
                J Offline
                JohnDaYe
                wrote on last edited by
                #7
                This post is deleted!
                1 Reply Last reply
                0
                • JonBJ JonB

                  @JohnDaYe

                  I think, I don't need to call dataChanged

                  ?

                  My advice would be: if @SGaist suggests you try something you heed it!

                  When you call beginResetModel Qt throws away all existing information about the model, including which row was selected. The view presumably then just remembers row #2 was selected and reselects that.

                  If instead you call dataChanged on each index it may remember which row in the model was selected and re-select the model row, not the view row number.

                  Otherwise, if that does not work or you wish to stick beginResetModel, before you sort you should store which row is selected by its content. That is usually the primary key, which looks like it might be your iNumber? Then after the sort you go find that row again by its content and reselect that. Any problem with that?

                  J Offline
                  J Offline
                  JohnDaYe
                  wrote on last edited by
                  #8

                  @JonB thanks
                  I try dataChanged, it does not work

                  and store selected and reselect is a good idea, but when I select large of data, it will be very slow,

                  QStandardItemModel is very fast, amazing

                  JonBJ 1 Reply Last reply
                  0
                  • J JohnDaYe

                    @JonB thanks
                    I try dataChanged, it does not work

                    and store selected and reselect is a good idea, but when I select large of data, it will be very slow,

                    QStandardItemModel is very fast, amazing

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by
                    #9

                    @JohnDaYe

                    and store selected and reselect is a good idea, but when I select large of data, it will be very slow,

                    Sorry, I don't understand? All you are supposed to store is the key of whichever row was previously selected, and then you re-find that in the new data order and select that item. What would be "slow"?

                    J 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @JohnDaYe

                      and store selected and reselect is a good idea, but when I select large of data, it will be very slow,

                      Sorry, I don't understand? All you are supposed to store is the key of whichever row was previously selected, and then you re-find that in the new data order and select that item. What would be "slow"?

                      J Offline
                      J Offline
                      JohnDaYe
                      wrote on last edited by
                      #10

                      @JonB
                      and then you re-find that in the new data order and select that item.

                      this is qml code
                      tableview.selection.select(index)

                      if i select 10000 items, it is every slowly

                      JonBJ 1 Reply Last reply
                      0
                      • J JohnDaYe

                        @JonB
                        and then you re-find that in the new data order and select that item.

                        this is qml code
                        tableview.selection.select(index)

                        if i select 10000 items, it is every slowly

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by
                        #11

                        @JohnDaYe
                        Let's be clear: I know nothing about QML.

                        tableview.selection.select(index)
                        

                        This selects one row, the row numbered index, right? So how does that select 10,000 items?

                        J 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @JohnDaYe
                          Let's be clear: I know nothing about QML.

                          tableview.selection.select(index)
                          

                          This selects one row, the row numbered index, right? So how does that select 10,000 items?

                          J Offline
                          J Offline
                          JohnDaYe
                          wrote on last edited by
                          #12

                          do
                          tableview.selection.select(index)
                          10000 times

                          JonBJ 1 Reply Last reply
                          0
                          • J JohnDaYe

                            do
                            tableview.selection.select(index)
                            10000 times

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by
                            #13

                            @JohnDaYe
                            Yes, but why in the world would you want to select a row 10,000 times, or reselect a given row 10,000 times?

                            I just don't get what you don't get?

                            1. Store the primary key of the currently selected row somewhere.
                            2. Call beginResetModel, do the sort, endResetModel.
                            3. Look through the rows in the newly-ordered model to find what the index is now of the row whose primary key you saved away. (Depending on what it's sorted by, this may be optimizable, or not.)
                            4. Call tableview.selection.select(index).

                            I haven't called select() 10,000 times, have I? I'm just selecting one row at the end.

                            J 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @JohnDaYe
                              Yes, but why in the world would you want to select a row 10,000 times, or reselect a given row 10,000 times?

                              I just don't get what you don't get?

                              1. Store the primary key of the currently selected row somewhere.
                              2. Call beginResetModel, do the sort, endResetModel.
                              3. Look through the rows in the newly-ordered model to find what the index is now of the row whose primary key you saved away. (Depending on what it's sorted by, this may be optimizable, or not.)
                              4. Call tableview.selection.select(index).

                              I haven't called select() 10,000 times, have I? I'm just selecting one row at the end.

                              J Offline
                              J Offline
                              JohnDaYe
                              wrote on last edited by JohnDaYe
                              #14

                              @JonB

                              Thanks
                              I will read QStandardItemModel source code and learn some idea from it!

                              all the end!

                              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