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. implementing sorting with QSortFilterProxyModel
Forum Update on Monday, May 27th 2025

implementing sorting with QSortFilterProxyModel

Scheduled Pinned Locked Moved Solved General and Desktop
27 Posts 5 Posters 3.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.
  • mzimmersM mzimmers

    @Ronel_qtmaster thanks for the example. I haven't gotten around to implementing my lessThan() function, because I'm still trying to figure out how/where to invoke the sort() call. This is what I'm trying:

    EquipmentValveProxy::EquipmentValveProxy(EquipmentModel *equipmentModel, QObject *parent)
        : QSortFilterProxyModel{parent}, m_equipmentModel(equipmentModel)
    {
        QObject::connect(m_equipmentModel, &EquipmentModel::modelUpdated, this, &EquipmentValveProxy::updateSorting);
    }
    
    void EquipmentValveProxy::updateSorting()
    {
        invalidate();
        sort(0); // what should I use for a column?
    }
    

    This is successful in that it gets me into my lessThan() function, currently stubbed as:

    bool EquipmentValveProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
    {
        bool rc = false;
    
        QVariant leftData = sourceModel()->data(left);
        QVariant rightData = sourceModel()->data(right);
        return rc;
    }
    

    Unfortunately, I'm still doing something wrong, because both leftData and rightData are invalid after assignments. How does this look to you?

    Thanks...

    Ronel_qtmasterR Offline
    Ronel_qtmasterR Offline
    Ronel_qtmaster
    wrote on last edited by
    #18

    @mzimmers said in implementing sorting with QSortFilterProxyModel:

    To invoque the sort , you just need to call QTableView::setSortingEnabled( true );

    In your EquipmentValveProxy class, you don't need any connect in the constructor, you only need to reimplement lessThan function.

    Now you need to pass the model containing your data to the sorter class.
    EquipmentValveProxy ::setSourceModel( &model );

    Then set the sorter class as model to your QTableView
    QTableView::setModel(&your_sorter_class);

    And finally enable sorting using QTableView::setSortingEnabled( true );

    mzimmersM 1 Reply Last reply
    1
    • Ronel_qtmasterR Ronel_qtmaster

      @mzimmers said in implementing sorting with QSortFilterProxyModel:

      To invoque the sort , you just need to call QTableView::setSortingEnabled( true );

      In your EquipmentValveProxy class, you don't need any connect in the constructor, you only need to reimplement lessThan function.

      Now you need to pass the model containing your data to the sorter class.
      EquipmentValveProxy ::setSourceModel( &model );

      Then set the sorter class as model to your QTableView
      QTableView::setModel(&your_sorter_class);

      And finally enable sorting using QTableView::setSortingEnabled( true );

      mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #19

      @Ronel_qtmaster said in implementing sorting with QSortFilterProxyModel:

      To invoque the sort , you just need to call QTableView::setSortingEnabled( true );

      But...it's a QML ListView, not a C++ TableView.

      Ronel_qtmasterR 1 Reply Last reply
      1
      • mzimmersM mzimmers

        @Ronel_qtmaster said in implementing sorting with QSortFilterProxyModel:

        To invoque the sort , you just need to call QTableView::setSortingEnabled( true );

        But...it's a QML ListView, not a C++ TableView.

        Ronel_qtmasterR Offline
        Ronel_qtmasterR Offline
        Ronel_qtmaster
        wrote on last edited by
        #20

        @mzimmers Okay.Then you should consider porting your model to qml https://doc.qt.io/qt-6/qtquick-modelviewsdata-cppmodels.html

        mzimmersM 1 Reply Last reply
        0
        • Ronel_qtmasterR Ronel_qtmaster

          @mzimmers Okay.Then you should consider porting your model to qml https://doc.qt.io/qt-6/qtquick-modelviewsdata-cppmodels.html

          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #21

          @Ronel_qtmaster said in implementing sorting with QSortFilterProxyModel:

          you should consider porting your model to qml

          I assume you mean making my model available to QML? I've done that. I've gone through (most of) the steps in the video from the link you provided.

          If you mean actually convert my model to a QML ListModel, that's not an option. My model code is ~1000 lines of C++ and fairly intricate; it's not conducive to conversion to QML.

          What I'm doing (with the connection) seems to be working. In the debugger, it's alarmingly slow, but when run normally, performance seems OK. Unless there's a serious flaw in this approach, I think it's what I have to do.

          GrecKoG 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @Ronel_qtmaster thanks for the example. I haven't gotten around to implementing my lessThan() function, because I'm still trying to figure out how/where to invoke the sort() call. This is what I'm trying:

            EquipmentValveProxy::EquipmentValveProxy(EquipmentModel *equipmentModel, QObject *parent)
                : QSortFilterProxyModel{parent}, m_equipmentModel(equipmentModel)
            {
                QObject::connect(m_equipmentModel, &EquipmentModel::modelUpdated, this, &EquipmentValveProxy::updateSorting);
            }
            
            void EquipmentValveProxy::updateSorting()
            {
                invalidate();
                sort(0); // what should I use for a column?
            }
            

            This is successful in that it gets me into my lessThan() function, currently stubbed as:

            bool EquipmentValveProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
            {
                bool rc = false;
            
                QVariant leftData = sourceModel()->data(left);
                QVariant rightData = sourceModel()->data(right);
                return rc;
            }
            

            Unfortunately, I'm still doing something wrong, because both leftData and rightData are invalid after assignments. How does this look to you?

            Thanks...

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #22

            @mzimmers said in implementing sorting with QSortFilterProxyModel:

            sort(0); // what should I use for a column?

            Not sure what your question is here? Only you know which column you want to sort by. If you go back to that full example I referenced on SO you will see they do indeed use m_messageProxyModel.sort(0, Qt::AscendingOrder); so that's the right thing to do.

            The QTableView widget has a setSortingEnabled(). If set that enables "sort arrows" on each column header so user can click to sort by any column. The view invokes the QSFPM::sort() method with corresponding column/direction. If that is what you want (end-user sorting) does your QML "grid" or "table" or whatever offer this? Otherwise have a look at the accepted solution in that SO thread:

            Alternatively, and if you want to do the sorting and filtering from QML and not c++, you could use my SortFilterProxyModel like so

            So that guy has written a complete QML interface to doing sort/filtering for you just like QSFPM for widgets! Don't look a gift horse in the mouth. (Don't actually know what you're supposed to do with one, because if you take it in you get invaded, so just looking at it in the mouth seems as safe as anything to me...) Either take the whole thing or look up how he does relevant bits? You did look at this when I first gave you the reference, didn't you? ;-)

            Unfortunately, I'm still doing something wrong, because both leftData and rightData are invalid after assignments. How does this look to you?

            What do you mean "invalid after assignments"? That should correctly pick up the QVariant values at the model indexes, whatever those value are.

            mzimmersM 1 Reply Last reply
            3
            • JonBJ JonB

              @mzimmers said in implementing sorting with QSortFilterProxyModel:

              sort(0); // what should I use for a column?

              Not sure what your question is here? Only you know which column you want to sort by. If you go back to that full example I referenced on SO you will see they do indeed use m_messageProxyModel.sort(0, Qt::AscendingOrder); so that's the right thing to do.

              The QTableView widget has a setSortingEnabled(). If set that enables "sort arrows" on each column header so user can click to sort by any column. The view invokes the QSFPM::sort() method with corresponding column/direction. If that is what you want (end-user sorting) does your QML "grid" or "table" or whatever offer this? Otherwise have a look at the accepted solution in that SO thread:

              Alternatively, and if you want to do the sorting and filtering from QML and not c++, you could use my SortFilterProxyModel like so

              So that guy has written a complete QML interface to doing sort/filtering for you just like QSFPM for widgets! Don't look a gift horse in the mouth. (Don't actually know what you're supposed to do with one, because if you take it in you get invaded, so just looking at it in the mouth seems as safe as anything to me...) Either take the whole thing or look up how he does relevant bits? You did look at this when I first gave you the reference, didn't you? ;-)

              Unfortunately, I'm still doing something wrong, because both leftData and rightData are invalid after assignments. How does this look to you?

              What do you mean "invalid after assignments"? That should correctly pick up the QVariant values at the model indexes, whatever those value are.

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #23

              @JonB said in implementing sorting with QSortFilterProxyModel:

              If you go back to that full example I referenced on SO you will see they do indeed use m_messageProxyModel.sort(0, Qt::AscendingOrder); so that's the right thing to do.

              Yeah, I figured out that wasn't the problem a little after I posted.

              The reason that my leftData and rightData variables were invalid were simply that I hadn't furnished a role from my model. I changed the lines to this:

                  QVariant leftData = sourceModel()->data(left, EquipmentModel::NameRole);
                  QVariant rightData = sourceModel()->data(right, EquipmentModel::NameRole);
              

              And now it works. Incredibly slow in the debugger, but otherwise fine.

              And yes, I did look at @GrecKo 's solution that he referenced on SO. If my needs become more elaborate than they currently are, I'll reconsider that option.

              1 Reply Last reply
              1
              • mzimmersM mzimmers has marked this topic as solved on
              • mzimmersM mzimmers

                @Ronel_qtmaster said in implementing sorting with QSortFilterProxyModel:

                you should consider porting your model to qml

                I assume you mean making my model available to QML? I've done that. I've gone through (most of) the steps in the video from the link you provided.

                If you mean actually convert my model to a QML ListModel, that's not an option. My model code is ~1000 lines of C++ and fairly intricate; it's not conducive to conversion to QML.

                What I'm doing (with the connection) seems to be working. In the debugger, it's alarmingly slow, but when run normally, performance seems OK. Unless there's a serious flaw in this approach, I think it's what I have to do.

                GrecKoG Offline
                GrecKoG Offline
                GrecKo
                Qt Champions 2018
                wrote on last edited by
                #24

                @mzimmers If your model is to be consumed in QML, it most likely has a single column and multiple roles if it's meant to be consumed by a ListView (multiple columns shouldn't be a thing unless you are implementing a spreadsheet, change my mind).

                call setDynamicSortFilter(true) and sort(0) once at the beginning and you should be good to go. Your lessThan function will be called when needed. Or use my project on GitHub like mentioned above. It hasn't been updated for a while but it is still relevant. Take a look at the available forks too, there might be improvements there.

                mzimmersM 1 Reply Last reply
                2
                • GrecKoG GrecKo

                  @mzimmers If your model is to be consumed in QML, it most likely has a single column and multiple roles if it's meant to be consumed by a ListView (multiple columns shouldn't be a thing unless you are implementing a spreadsheet, change my mind).

                  call setDynamicSortFilter(true) and sort(0) once at the beginning and you should be good to go. Your lessThan function will be called when needed. Or use my project on GitHub like mentioned above. It hasn't been updated for a while but it is still relevant. Take a look at the available forks too, there might be improvements there.

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #25

                  @GrecKo said in implementing sorting with QSortFilterProxyModel:

                  call setDynamicSortFilter(true) and sort(0) once at the beginning and you should be good to go.

                  Is this true even if the source model adds or deletes list elements?

                  GrecKoG 1 Reply Last reply
                  0
                  • mzimmersM mzimmers has marked this topic as unsolved on
                  • mzimmersM mzimmers has marked this topic as solved on
                  • mzimmersM mzimmers

                    @GrecKo said in implementing sorting with QSortFilterProxyModel:

                    call setDynamicSortFilter(true) and sort(0) once at the beginning and you should be good to go.

                    Is this true even if the source model adds or deletes list elements?

                    GrecKoG Offline
                    GrecKoG Offline
                    GrecKo
                    Qt Champions 2018
                    wrote on last edited by
                    #26

                    It is.​​​​​

                    JonBJ 1 Reply Last reply
                    0
                    • GrecKoG GrecKo

                      It is.​​​​​

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #27

                      @GrecKo
                      https://stackoverflow.com/questions/45563393/sort-the-data-of-a-qml-listview-by-using-a-qsortfilterproxymodel
                      https://github.com/oKcerG/SortFilterProxyModel/

                      OIC you were the replier & author :)

                      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