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` incorrect mapping indexes from source model
Forum Updated to NodeBB v4.3 + New Features

`QSortFilterProxyModel` incorrect mapping indexes from source model

Scheduled Pinned Locked Moved Unsolved General and Desktop
17 Posts 3 Posters 973 Views 1 Watching
  • 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #2

    @Please_Help_me_D said in `QSortFilterProxyModel` incorrect mapping indexes from source model:

    This seems to be fixed and tested when I don't insert/append new row

    Is this related to https://doc.qt.io/qt-6/qsortfilterproxymodel.html#dynamicSortFilter-prop

    Note that you should not update the source model through the proxy model when dynamicSortFilter is true.

    ?

    Please_Help_me_DP 1 Reply Last reply
    2
    • JonBJ JonB

      @Please_Help_me_D said in `QSortFilterProxyModel` incorrect mapping indexes from source model:

      This seems to be fixed and tested when I don't insert/append new row

      Is this related to https://doc.qt.io/qt-6/qsortfilterproxymodel.html#dynamicSortFilter-prop

      Note that you should not update the source model through the proxy model when dynamicSortFilter is true.

      ?

      Please_Help_me_DP Offline
      Please_Help_me_DP Offline
      Please_Help_me_D
      wrote on last edited by
      #3

      @JonB thank you for the hint!

      I didn't modify dynamicSortFilter for that proxy but I have to duble check this as I have a feeling this may be the reason of that.

      I will comeback with the results of testing!

      JonBJ 1 Reply Last reply
      0
      • Please_Help_me_DP Please_Help_me_D

        @JonB thank you for the hint!

        I didn't modify dynamicSortFilter for that proxy but I have to duble check this as I have a feeling this may be the reason of that.

        I will comeback with the results of testing!

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

        @Please_Help_me_D You are supposed to modify it off default (true) if you are doing what it says. At any rate try setting it false and see if that modifies behaviour?

        Please_Help_me_DP 1 Reply Last reply
        1
        • JonBJ JonB

          @Please_Help_me_D You are supposed to modify it off default (true) if you are doing what it says. At any rate try setting it false and see if that modifies behaviour?

          Please_Help_me_DP Offline
          Please_Help_me_DP Offline
          Please_Help_me_D
          wrote on last edited by
          #5

          @JonB I've tried setting dynamicSortFilter to True and False but unfortunately that didn't help...

          I have a feeling that source model either doesn't send some signal when new row is added or the connection type between proxy model and source model is not the default so it there is no time to proxy receives and process the signal. I will try to look into the source code of these models.

          JonBJ 1 Reply Last reply
          0
          • Please_Help_me_DP Please_Help_me_D

            @JonB I've tried setting dynamicSortFilter to True and False but unfortunately that didn't help...

            I have a feeling that source model either doesn't send some signal when new row is added or the connection type between proxy model and source model is not the default so it there is no time to proxy receives and process the signal. I will try to look into the source code of these models.

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

            @Please_Help_me_D
            "Timing" cannot/should not be an issue.
            If it's your own source model make sure you do the right thing for insertRows per the docs. There is a also a model tester per https://doc.qt.io/qt-6/qabstractitemmodeltester.html. Oh if you are using base QStandardItemModel then obviously it behaves correctly.

            Otherwise please show a complete but minimal example of what goes wrong.

            Just glancing and thinking:

            d->model->insertRow(d->model->rowCount());
            
            int proxy_row = d->proxy->mapFromSource(
                d->model->index(row, 0)).row();       //  proxy_row is incorrect!!!
            

            First line inserts a new blank row. Meaning all columns are empty/QVariant(). So if you are sorting (ascending) by anything it will likely come first, so proxy row will be 0. So that seems correct to me. I think you need to clarify exactly what you think is wrong.

            Please_Help_me_DP 1 Reply Last reply
            1
            • JonBJ JonB

              @Please_Help_me_D
              "Timing" cannot/should not be an issue.
              If it's your own source model make sure you do the right thing for insertRows per the docs. There is a also a model tester per https://doc.qt.io/qt-6/qabstractitemmodeltester.html. Oh if you are using base QStandardItemModel then obviously it behaves correctly.

              Otherwise please show a complete but minimal example of what goes wrong.

              Just glancing and thinking:

              d->model->insertRow(d->model->rowCount());
              
              int proxy_row = d->proxy->mapFromSource(
                  d->model->index(row, 0)).row();       //  proxy_row is incorrect!!!
              

              First line inserts a new blank row. Meaning all columns are empty/QVariant(). So if you are sorting (ascending) by anything it will likely come first, so proxy row will be 0. So that seems correct to me. I think you need to clarify exactly what you think is wrong.

              Please_Help_me_DP Offline
              Please_Help_me_DP Offline
              Please_Help_me_D
              wrote on last edited by
              #7

              @JonB I successfully created minimal project that shows the
              issue.

              link to the minimal example project to Download

              Steps to reproduce:

              1. build and run the app
              2. click on Add file button
              3. add several arbitrary files
              4. manually resort the table view by cicking on the File column name
              5. click Add file and add few more files
              6. look at the resulted table

              Here is the result. As you can see there is blank cells because proxy_row is incorrect.

              a2ed6a20-647e-45c8-abc3-ff5bd3e1e036-image.png

              Christian EhrlicherC 1 Reply Last reply
              0
              • Please_Help_me_DP Please_Help_me_D

                @JonB I successfully created minimal project that shows the
                issue.

                link to the minimal example project to Download

                Steps to reproduce:

                1. build and run the app
                2. click on Add file button
                3. add several arbitrary files
                4. manually resort the table view by cicking on the File column name
                5. click Add file and add few more files
                6. look at the resulted table

                Here is the result. As you can see there is blank cells because proxy_row is incorrect.

                a2ed6a20-647e-45c8-abc3-ff5bd3e1e036-image.png

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #8

                Because the sorting happens during insertion the row is wrong afterwards.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                Please_Help_me_DP 1 Reply Last reply
                3
                • Christian EhrlicherC Christian Ehrlicher

                  Because the sorting happens during insertion the row is wrong afterwards.

                  Please_Help_me_DP Offline
                  Please_Help_me_DP Offline
                  Please_Help_me_D
                  wrote on last edited by
                  #9

                  @Christian-Ehrlicher hi,

                  You mean the blank row is inserted and it becomes the first row in the proxy model? But in this case this first proxy row is not filled anyway in the example.

                  Can't understand the logic...

                  Christian EhrlicherC 1 Reply Last reply
                  0
                  • Please_Help_me_DP Please_Help_me_D

                    @Christian-Ehrlicher hi,

                    You mean the blank row is inserted and it becomes the first row in the proxy model? But in this case this first proxy row is not filled anyway in the example.

                    Can't understand the logic...

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #10

                    When you want the correct (source) index then use QStandardItemModel::indexFromItem()

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    Please_Help_me_DP 1 Reply Last reply
                    3
                    • Christian EhrlicherC Christian Ehrlicher

                      When you want the correct (source) index then use QStandardItemModel::indexFromItem()

                      Please_Help_me_DP Offline
                      Please_Help_me_DP Offline
                      Please_Help_me_D
                      wrote on last edited by Please_Help_me_D
                      #11

                      @Christian-Ehrlicher thank you, this works fine with C++ only:

                      void MainWindow::onAddBtnClicked(){
                        QStringList fileNames = QFileDialog::getOpenFileNames(
                            nullptr, QObject::tr("Select one or more files to open"), "",
                            QObject::tr("all (*)"));
                      
                        for (const auto &name : fileNames) {
                          // set item directly to the model (works fine)
                          QStandardItem *readFileItem = new QStandardItem(name);
                          readFileItem->setFlags(readFileItem->flags() & ~Qt::ItemIsEditable);
                          model->setItem(model->rowCount(), 0, readFileItem);
                      
                          QModelIndex index = model->indexFromItem(readFileItem);
                          int row = index.row();
                          int proxy_row = proxy->mapFromSource(
                                model->index(row, 0)).row();
                      
                          // set data to the proxy (gives blank cells)
                          proxy->setData(
                                proxy->index(proxy_row, 1),
                                QString::number(row));
                          proxy->setData(
                                proxy->index(proxy_row, 2),
                                QString::number(proxy_row));
                        }
                      }
                      

                      The problem now is that approach doesn't work with PythonQt.
                      As I mentionned my application includes both C++ and python so that it is posible to run python scripts and new GUI appears with PythonQt force.

                      I tried your approach in python script and it didn't work. For example after manual column resorting I get:

                      row: 4,     proxy_row: 0
                      row: 5,     proxy_row: 0
                      row: 6,     proxy_row: 0
                      

                      And this is how it looks in Python:

                            readFileItem = QtGui.QStandardItem(name)
                            readFileItem.setFlags(readFileItem.flags() & ~Qt.Qt.ItemIsEditable)
                            self.wellModel.setItem(self.wellModel.rowCount(), self.wellTableHdrNames.index("read file"), readFileItem)
                      
                            index = self.wellModel.indexFromItem(readFileItem)
                            row = index.row()
                            proxy_row = self.wellProxy.mapFromSource(index).row();
                      
                      Christian EhrlicherC 1 Reply Last reply
                      0
                      • Please_Help_me_DP Please_Help_me_D

                        @Christian-Ehrlicher thank you, this works fine with C++ only:

                        void MainWindow::onAddBtnClicked(){
                          QStringList fileNames = QFileDialog::getOpenFileNames(
                              nullptr, QObject::tr("Select one or more files to open"), "",
                              QObject::tr("all (*)"));
                        
                          for (const auto &name : fileNames) {
                            // set item directly to the model (works fine)
                            QStandardItem *readFileItem = new QStandardItem(name);
                            readFileItem->setFlags(readFileItem->flags() & ~Qt::ItemIsEditable);
                            model->setItem(model->rowCount(), 0, readFileItem);
                        
                            QModelIndex index = model->indexFromItem(readFileItem);
                            int row = index.row();
                            int proxy_row = proxy->mapFromSource(
                                  model->index(row, 0)).row();
                        
                            // set data to the proxy (gives blank cells)
                            proxy->setData(
                                  proxy->index(proxy_row, 1),
                                  QString::number(row));
                            proxy->setData(
                                  proxy->index(proxy_row, 2),
                                  QString::number(proxy_row));
                          }
                        }
                        

                        The problem now is that approach doesn't work with PythonQt.
                        As I mentionned my application includes both C++ and python so that it is posible to run python scripts and new GUI appears with PythonQt force.

                        I tried your approach in python script and it didn't work. For example after manual column resorting I get:

                        row: 4,     proxy_row: 0
                        row: 5,     proxy_row: 0
                        row: 6,     proxy_row: 0
                        

                        And this is how it looks in Python:

                              readFileItem = QtGui.QStandardItem(name)
                              readFileItem.setFlags(readFileItem.flags() & ~Qt.Qt.ItemIsEditable)
                              self.wellModel.setItem(self.wellModel.rowCount(), self.wellTableHdrNames.index("read file"), readFileItem)
                        
                              index = self.wellModel.indexFromItem(readFileItem)
                              row = index.row()
                              proxy_row = self.wellProxy.mapFromSource(index).row();
                        
                        Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #12

                        If it works in c++ then it also works the same way in python except you don't use python correctly (which i can't justify) so you must be doing something wrong.
                        Why do you need the index at all when using a QStandardItemModel?

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        Please_Help_me_DP 1 Reply Last reply
                        2
                        • Christian EhrlicherC Christian Ehrlicher

                          If it works in c++ then it also works the same way in python except you don't use python correctly (which i can't justify) so you must be doing something wrong.
                          Why do you need the index at all when using a QStandardItemModel?

                          Please_Help_me_DP Offline
                          Please_Help_me_DP Offline
                          Please_Help_me_D
                          wrote on last edited by
                          #13

                          @Christian-Ehrlicher absolutely agree it shpuld work with python too.

                          @Christian-Ehrlicher said in `QSortFilterProxyModel` incorrect mapping indexes from source model:

                          Why do you need the index at all when using a QStandardItemModel?

                          The idea is that user adds files to the table and then the information about every chosen file is filled in table with proxyModel.setData(w_proxy_row, ...):

                          self.wellProxy.setData(self.wellProxy.index(w_proxy_row, 1), well_name)
                          

                          I know I can set data directly to the source model but I'm trying to avoid that though I don't remeber exactly why and use proxy_model.

                          Christian EhrlicherC 1 Reply Last reply
                          0
                          • Please_Help_me_DP Please_Help_me_D

                            @Christian-Ehrlicher absolutely agree it shpuld work with python too.

                            @Christian-Ehrlicher said in `QSortFilterProxyModel` incorrect mapping indexes from source model:

                            Why do you need the index at all when using a QStandardItemModel?

                            The idea is that user adds files to the table and then the information about every chosen file is filled in table with proxyModel.setData(w_proxy_row, ...):

                            self.wellProxy.setData(self.wellProxy.index(w_proxy_row, 1), well_name)
                            

                            I know I can set data directly to the source model but I'm trying to avoid that though I don't remeber exactly why and use proxy_model.

                            Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #14

                            Then either use the proxy_index or - since you're using a QStandardItemModel, set it through the QStandardItemModel. Don't see a problem here.

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            Please_Help_me_DP 1 Reply Last reply
                            1
                            • Christian EhrlicherC Christian Ehrlicher

                              Then either use the proxy_index or - since you're using a QStandardItemModel, set it through the QStandardItemModel. Don't see a problem here.

                              Please_Help_me_DP Offline
                              Please_Help_me_DP Offline
                              Please_Help_me_D
                              wrote on last edited by
                              #15

                              @Christian-Ehrlicher proxy_index you mean the one I get with:

                                    index = self.wellModel.indexFromItem(readFileItem)
                                    row = index.row()
                                    proxy_index = self.wellProxy.mapFromSource(index)
                              

                              ?

                              Christian EhrlicherC 1 Reply Last reply
                              0
                              • Please_Help_me_DP Please_Help_me_D

                                @Christian-Ehrlicher proxy_index you mean the one I get with:

                                      index = self.wellModel.indexFromItem(readFileItem)
                                      row = index.row()
                                      proxy_index = self.wellProxy.mapFromSource(index)
                                

                                ?

                                Christian EhrlicherC Offline
                                Christian EhrlicherC Offline
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on last edited by
                                #16

                                Yes, that's the proxy index.

                                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                Visit the Qt Academy at https://academy.qt.io/catalog

                                Please_Help_me_DP 1 Reply Last reply
                                1
                                • Christian EhrlicherC Christian Ehrlicher

                                  Yes, that's the proxy index.

                                  Please_Help_me_DP Offline
                                  Please_Help_me_DP Offline
                                  Please_Help_me_D
                                  wrote on last edited by
                                  #17

                                  @Christian-Ehrlicher alright I just decided to forbid table view sorting for the python side.

                                  It is strange that C++ side works and Python fails. But there are some chances that the reason of that is my personal additions so I will take some time to investigate it.

                                  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