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 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