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. QSortFilterProxyModel, QAbstractItemModel

QSortFilterProxyModel, QAbstractItemModel

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 3 Posters 2.5k 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.
  • S Offline
    S Offline
    Slawomir_Piernikowski
    wrote on last edited by Slawomir_Piernikowski
    #1

    Hi
    When data sort itself in TableView for example when clicking on a header of a column arrow or editing and setData in a cell of the TableView the order of model objects in the model container not correspond the order of the data in a TableView.
    I have customized QSortFilterProxyModel so for sotring is responsible QSortFilterProxyModel::Sort function.

    I give some example to let somebody to easier to understand what is about:
    Hereunder is printed from model container just after sort was executed on the TableView:
    (data order in the model container)
    Magazyn categories: "ZZZ"
    Magazyn categories: "XXX"
    Magazyn categories: "QQQ"
    Magazyn categories: "AAA"

    (data order in the tableView is what I see in the TableView)
    Magazyn categories: "AAA"
    Magazyn categories: "QQQ"
    Magazyn categories: "XXX"
    Magazyn categories: "ZZZ"

    So the order of the data in the Tableview is different than in the model(QAbstractTableModel). Why is it so?

    JonBJ 1 Reply Last reply
    0
    • S Slawomir_Piernikowski

      Hi
      When data sort itself in TableView for example when clicking on a header of a column arrow or editing and setData in a cell of the TableView the order of model objects in the model container not correspond the order of the data in a TableView.
      I have customized QSortFilterProxyModel so for sotring is responsible QSortFilterProxyModel::Sort function.

      I give some example to let somebody to easier to understand what is about:
      Hereunder is printed from model container just after sort was executed on the TableView:
      (data order in the model container)
      Magazyn categories: "ZZZ"
      Magazyn categories: "XXX"
      Magazyn categories: "QQQ"
      Magazyn categories: "AAA"

      (data order in the tableView is what I see in the TableView)
      Magazyn categories: "AAA"
      Magazyn categories: "QQQ"
      Magazyn categories: "XXX"
      Magazyn categories: "ZZZ"

      So the order of the data in the Tableview is different than in the model(QAbstractTableModel). Why is it so?

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

      @Slawomir_Piernikowski said in QSortFilterProxyModel, QAbstractItemModel:

      So the order of the data in the view is different than in the model.

      Which model are you talking about? The QSortFilterProxyModel or the underlying model it is a proxy for? (BTW, QTableView does not do its own sorting, if that's what you think it does, it passes the sorting to its model.)

      1 Reply Last reply
      2
      • S Offline
        S Offline
        Slawomir_Piernikowski
        wrote on last edited by Slawomir_Piernikowski
        #3

        Which model are you talking about?:
        Castomized QAbstractTableModel

        For sorting in this case is responsible QSortFilterProxyModel::Sort function I only trigger this function by calling SetData function of The QAbstractTableModel or by clicking an arrow on header column of the TableView which is responsible for calling also QSortFilterProxyModel::Sort function

        So the order of the data in the Tableview is different than in the model(QAbstractTableModel).

        VRoninV 1 Reply Last reply
        0
        • S Slawomir_Piernikowski

          Which model are you talking about?:
          Castomized QAbstractTableModel

          For sorting in this case is responsible QSortFilterProxyModel::Sort function I only trigger this function by calling SetData function of The QAbstractTableModel or by clicking an arrow on header column of the TableView which is responsible for calling also QSortFilterProxyModel::Sort function

          So the order of the data in the Tableview is different than in the model(QAbstractTableModel).

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          @Slawomir_Piernikowski said in QSortFilterProxyModel, QAbstractItemModel:

          So the order of the data in the Tableview is different than in the model

          Correct, that's what QSortFilterProxyModel does. It's 50% of its job (the remaining being the filtering part)

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          S 1 Reply Last reply
          2
          • VRoninV VRonin

            @Slawomir_Piernikowski said in QSortFilterProxyModel, QAbstractItemModel:

            So the order of the data in the Tableview is different than in the model

            Correct, that's what QSortFilterProxyModel does. It's 50% of its job (the remaining being the filtering part)

            S Offline
            S Offline
            Slawomir_Piernikowski
            wrote on last edited by
            #5

            @VRonin You said : Correct, that's what QSortFilterProxyModel does. It's 50% of its job (the remaining being the filtering part)
            If QSortFilterProxyModel::Sort function sorts data which I see in the TableView Why my
            model(customized QAbsrtractTableModel) data are not sorted????

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              That's exactly what QSortFilterProxyModel model do. It reorders the indexes and maintain a mapping between its indexes and those of the source model.
              You can imagine it as a telephone switchboard but operating on the model indexes

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              S 1 Reply Last reply
              3
              • VRoninV VRonin

                That's exactly what QSortFilterProxyModel model do. It reorders the indexes and maintain a mapping between its indexes and those of the source model.
                You can imagine it as a telephone switchboard but operating on the model indexes

                S Offline
                S Offline
                Slawomir_Piernikowski
                wrote on last edited by Slawomir_Piernikowski
                #7

                @VRonin ok but I need to have model data reorded the same way as the data are sorted and seen in the view

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #8

                  Then you have to ditch the QSortFilterProxyModel and reimplement sort in your custom QAbstractItemModel emitting layoutAboutToBeChanged and layoutChanged and calling changePersistentIndexes

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  S 1 Reply Last reply
                  2
                  • VRoninV VRonin

                    Then you have to ditch the QSortFilterProxyModel and reimplement sort in your custom QAbstractItemModel emitting layoutAboutToBeChanged and layoutChanged and calling changePersistentIndexes

                    S Offline
                    S Offline
                    Slawomir_Piernikowski
                    wrote on last edited by Slawomir_Piernikowski
                    #9

                    @VRonin I need QSortFilterProxyModel for I use it also for filtring data of the model.
                    I also need to have consitency of the model(QAbstractTableModel) data and the data after sorting using QSortFilterProxyModel::Sort function.

                    Maybe mapToSource and mapFormSource functions will be helpfull??????

                    JonBJ 1 Reply Last reply
                    0
                    • S Slawomir_Piernikowski

                      @VRonin I need QSortFilterProxyModel for I use it also for filtring data of the model.
                      I also need to have consitency of the model(QAbstractTableModel) data and the data after sorting using QSortFilterProxyModel::Sort function.

                      Maybe mapToSource and mapFormSource functions will be helpfull??????

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

                      @Slawomir_Piernikowski
                      For the record, we're not sure why you want the underlying data model to have the same sort order as the in the proxy model?

                      Data doesn't really have a sort order, sorting is just one way of viewing the data. At different times you might sort by different criteria. The proxy model also provides filtering for the view, but you don't say you want rows omitted by the filter to be removed from the underlying model, which would be the equivalent change to what you are asking about sorting?

                      S 1 Reply Last reply
                      2
                      • JonBJ JonB

                        @Slawomir_Piernikowski
                        For the record, we're not sure why you want the underlying data model to have the same sort order as the in the proxy model?

                        Data doesn't really have a sort order, sorting is just one way of viewing the data. At different times you might sort by different criteria. The proxy model also provides filtering for the view, but you don't say you want rows omitted by the filter to be removed from the underlying model, which would be the equivalent change to what you are asking about sorting?

                        S Offline
                        S Offline
                        Slawomir_Piernikowski
                        wrote on last edited by Slawomir_Piernikowski
                        #11

                        @JonB You wrote: we're not sure why you want the underlying data model to have the same sort order as the in the proxy model?
                        For during setting data(call SetData function of the customized QAbstractTableModel) or simpler saying clicking on a cell in the TableView and alter the data in it I take the:
                        int justRemovedRowIndex = cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex().row();
                        and everything is working perfectly if sorting is not involved.

                        VRoninV 1 Reply Last reply
                        0
                        • S Slawomir_Piernikowski

                          @JonB You wrote: we're not sure why you want the underlying data model to have the same sort order as the in the proxy model?
                          For during setting data(call SetData function of the customized QAbstractTableModel) or simpler saying clicking on a cell in the TableView and alter the data in it I take the:
                          int justRemovedRowIndex = cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex().row();
                          and everything is working perfectly if sorting is not involved.

                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #12

                          @Slawomir_Piernikowski said in QSortFilterProxyModel, QAbstractItemModel:

                          int justRemovedRowIndex = cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex().row();

                          No idea what this means, you gave us 0 context to any of those symbols

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          S 1 Reply Last reply
                          0
                          • VRoninV VRonin

                            @Slawomir_Piernikowski said in QSortFilterProxyModel, QAbstractItemModel:

                            int justRemovedRowIndex = cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex().row();

                            No idea what this means, you gave us 0 context to any of those symbols

                            S Offline
                            S Offline
                            Slawomir_Piernikowski
                            wrote on last edited by
                            #13

                            @VRonin
                            int justRemovedRowIndex = cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex().row();

                            1. cMagazynView - pointer to class which have a member...
                              ... QVector<MagazynView *>vectMagazyn; - vector of MagazynView pointers
                              GetTabView() -
                            QTableView &MagazynView::GetTabView()
                            {
                               return *tabView;
                            }
                            

                            As it is simply to see I want to get row number of the currentIndex row of the TableView

                            JonBJ 1 Reply Last reply
                            0
                            • S Slawomir_Piernikowski

                              @VRonin
                              int justRemovedRowIndex = cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex().row();

                              1. cMagazynView - pointer to class which have a member...
                                ... QVector<MagazynView *>vectMagazyn; - vector of MagazynView pointers
                                GetTabView() -
                              QTableView &MagazynView::GetTabView()
                              {
                                 return *tabView;
                              }
                              

                              As it is simply to see I want to get row number of the currentIndex row of the TableView

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

                              @Slawomir_Piernikowski
                              As @VRonin has said, you have two approaches to sorting data from the model. Either you do not use a QSortFilterProxyModel and do the actual sorting yourself on the rows, or you do use it and the sorting happens in the proxy not the underlying data. Then, yes, you must "dereference" to get the actual index in the underlying data from the proxy, and for that you have https://doc.qt.io/qt-5/qsortfilterproxymodel.html#mapToSource. That's just how it is.

                              S 1 Reply Last reply
                              1
                              • VRoninV Offline
                                VRoninV Offline
                                VRonin
                                wrote on last edited by VRonin
                                #15

                                QSortFilterProxyModel has a method to map back the index of the view to the original model: https://doc.qt.io/qt-5/qsortfilterproxymodel.html#mapToSource

                                Instead of using currentIndex().row() you can use proxyModel->mapToSource(currentIndex()).row()

                                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                ~Napoleon Bonaparte

                                On a crusade to banish setIndexWidget() from the holy land of Qt

                                S 1 Reply Last reply
                                2
                                • JonBJ JonB

                                  @Slawomir_Piernikowski
                                  As @VRonin has said, you have two approaches to sorting data from the model. Either you do not use a QSortFilterProxyModel and do the actual sorting yourself on the rows, or you do use it and the sorting happens in the proxy not the underlying data. Then, yes, you must "dereference" to get the actual index in the underlying data from the proxy, and for that you have https://doc.qt.io/qt-5/qsortfilterproxymodel.html#mapToSource. That's just how it is.

                                  S Offline
                                  S Offline
                                  Slawomir_Piernikowski
                                  wrote on last edited by
                                  #16

                                  @JonB ok thanks

                                  1 Reply Last reply
                                  0
                                  • VRoninV VRonin

                                    QSortFilterProxyModel has a method to map back the index of the view to the original model: https://doc.qt.io/qt-5/qsortfilterproxymodel.html#mapToSource

                                    Instead of using currentIndex().row() you can use proxyModel->mapToSource(currentIndex()).row()

                                    S Offline
                                    S Offline
                                    Slawomir_Piernikowski
                                    wrote on last edited by
                                    #17

                                    @VRonin ok I will try to use this

                                    1 Reply Last reply
                                    0
                                    • S Offline
                                      S Offline
                                      Slawomir_Piernikowski
                                      wrote on last edited by
                                      #18

                                      After a fiew tests it looks like mapToSource did the trick.

                                      auto magazynToBeRemoved = model->GetcMagazynVect().at(cFilterProxyModel->GetVectMagazynFilterProxyModel().at(index)->mapToSource(cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex()).row());
                                      
                                      JonBJ 1 Reply Last reply
                                      2
                                      • S Slawomir_Piernikowski

                                        After a fiew tests it looks like mapToSource did the trick.

                                        auto magazynToBeRemoved = model->GetcMagazynVect().at(cFilterProxyModel->GetVectMagazynFilterProxyModel().at(index)->mapToSource(cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex()).row());
                                        
                                        JonBJ Offline
                                        JonBJ Offline
                                        JonB
                                        wrote on last edited by
                                        #19

                                        @Slawomir_Piernikowski
                                        Good. But do you really write that as a single line in your source code?

                                        S 1 Reply Last reply
                                        1
                                        • JonBJ JonB

                                          @Slawomir_Piernikowski
                                          Good. But do you really write that as a single line in your source code?

                                          S Offline
                                          S Offline
                                          Slawomir_Piernikowski
                                          wrote on last edited by Slawomir_Piernikowski
                                          #20

                                          @JonB I know that it can be not so readable for everybody but since I have been working on my soft from allmost 8 monthes I am used to such long lines of code :-)). Usually I devided such a long lines of code like this:

                                          auto magazynToBeRemoved = model->GetcMagazynVect().at(cFilterProxyModel->GetVectMagazynFilterProxyModel().at(index)->
                                          
                                          mapToSource(cMagazynView->GetVectMagazyn().at(index)->GetTabView().currentIndex()).row());
                                          
                                          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