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. Sorting Breaks the Selection When a New Column is Added to the SubClassed Model
QtWS25 Last Chance

Sorting Breaks the Selection When a New Column is Added to the SubClassed Model

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 265 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.
  • D Offline
    D Offline
    DzCode
    wrote on last edited by
    #1

    Hi all,

    We are using a custom QSortFilterProxyModel. We have mapToSource and mapFromSource methods. Before sorting there was no problem about adding new columns to the proxy model.

    Before proxy the codes like below:

    QModelIndex ProxyModel::index(int in_row, int in_column, const QModelIndex &in_parent) const
    {
        Q_UNUSED(in_parent);
    
        if (0 > in_row || 0 > in_column || in_row > this->rowCount() || in_column > this->columnCount())
            return QModelIndex();
    
        return createIndex(in_row, in_column);
    }
    QModelIndex ProxyModel::parent(const QModelIndex &in_child) const
    {
        Q_UNUSED(in_child);
        return QModelIndex();
    }
    QModelIndex ProxyModel::mapToSource(const QModelIndex &in_proxy_index) const
    {
        if (false == in_proxy_index.isValid())
            return QModelIndex();
    
        Q_ASSERT(this == in_proxy_index.model());
    
        if(0 == m_proxy_column_indexes.size() && 0 == m_proxy_row_indexes.size())
        {
            return sourceModel()->index(in_proxy_index.row(), in_proxy_index.column());
        }
        else
        {
            int added_column_indexes = 0;
            for (int proxy_column_index : m_proxy_column_indexes)
            {
                if(in_proxy_index.column() == proxy_column_index)
                {
                    return QModelIndex();
                }
                else if(in_proxy_index.column() > proxy_column_index)
                {
                    added_column_indexes++;
                }
                else
                {
                    break;
                }
            }
            int added_row_indexes = 0;
            for (int proxy_row_index : m_proxy_row_indexes)
            {
                if(in_proxy_index.row() == proxy_row_index)
                {
                    return QModelIndex();
                }
                else if(in_proxy_index.row() > proxy_row_index)
                {
                    added_row_indexes++;
                }
                else
                {
                    break;
                }
            }
            return sourceModel()->index(in_proxy_index.row() - added_row_indexes, in_proxy_index.column() - added_column_indexes);
        }
    }
    QModelIndex ProxyModel::mapFromSource(const QModelIndex &in_source_index) const
    {
        if (false == in_source_index.isValid())
            return QModelIndex();
    
        if(0 == m_proxy_column_indexes.size() && 0 == m_proxy_row_indexes.size())
        {
            return index(in_source_index.row(), in_source_index.column());
        }
        else
        {
            int added_column_indexes = 0;
            for (int proxy_column_index : m_proxy_column_indexes)
            {
                if(in_source_index.column() > proxy_column_index)
                {
                    added_column_indexes++;
                }
                else
                {
                    break;
                }
            }
            int added_row_indexes = 0;
            for (int proxy_row_index : m_proxy_row_indexes)
            {
                if(in_source_index.row() > proxy_row_index)
                {
                    added_row_indexes++;
                }
                else
                {
                    break;
                }
            }
            return index(in_source_index.row() + added_row_indexes, in_source_index.column() + added_column_indexes);
        }
    }
    
    void ProxyModel::insertProxyColumn(const int in_column_index)
    {
        beginInsertColumns(QModelIndex(),in_column_index, in_column_index);
        if (false == (0 > in_column_index || in_column_index >= columnCount()))
        {
            m_proxy_column_indexes.append(in_column_index);
            std::sort(m_proxy_column_indexes.begin(),m_proxy_column_indexes.end(),std::less<int>());
        }
        endInsertColumns();
    }
    

    After changes to apply sorting:
    We deleted index and parent and change the return of mapping methods like below (our index and parent methods gives an error):
    2020-08-05 14_01_46-ProxyModel.cpp (Ui_WidgetsLib_src_TableView @ AVLDriveCore) - Qt Creator.png

    return QSortFilterProxyModel::mapToSource(index(in_proxy_index.row() - added_row_indexes, in_proxy_index.column() - added_column_indexes));
    
    return QSortFilterProxyModel::mapFromSource(sourceModel()->index(in_source_index.row() + added_row_indexes, in_source_index.column() + added_column_indexes));
    

    If we do not use parent class'es mapping methods we cannot sort our custom model. However, this implementation breaks selection model of tableview and also some columns disappears at the end. Can you help us to solve the problem

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

      Hi,

      I think it would be simpler to have one proxy that adds your special columns and on top of that one use QSortFilterProxyModel. This will avoid trying to do two different things with the same class.

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

      D 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        I think it would be simpler to have one proxy that adds your special columns and on top of that one use QSortFilterProxyModel. This will avoid trying to do two different things with the same class.

        D Offline
        D Offline
        DzCode
        wrote on last edited by
        #3

        @SGaist but it means I should have 2 proxy subclass, which is not a good solution. I know that If I gave the this model as a soruce to another qsortfilterproxymodel I can sort without side effects, but in this case we have use setModel() method of qtableview subclass. At first I coded it, but there should be another way to do it. This way looks like cheating a little.

        Also, the custom proxymodel is used to do everything inside the tableview since we do not want to change anything inside the source. You can think our proxymodel is an internal mdel inside the tableview

        JonBJ 1 Reply Last reply
        0
        • D DzCode

          @SGaist but it means I should have 2 proxy subclass, which is not a good solution. I know that If I gave the this model as a soruce to another qsortfilterproxymodel I can sort without side effects, but in this case we have use setModel() method of qtableview subclass. At first I coded it, but there should be another way to do it. This way looks like cheating a little.

          Also, the custom proxymodel is used to do everything inside the tableview since we do not want to change anything inside the source. You can think our proxymodel is an internal mdel inside the tableview

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

          @DzCode said in Sorting Breaks the Selection When a New Column is Added to the SubClassed Model:

          @SGaist but it means I should have 2 proxy subclass, which is not a good solution
          This way looks like cheating a little.

          Why do you say that? Having two separate proxies which do two different things separately, as @SGaist suggests, can be a very good way of approaching things....

          D 1 Reply Last reply
          1
          • JonBJ JonB

            @DzCode said in Sorting Breaks the Selection When a New Column is Added to the SubClassed Model:

            @SGaist but it means I should have 2 proxy subclass, which is not a good solution
            This way looks like cheating a little.

            Why do you say that? Having two separate proxies which do two different things separately, as @SGaist suggests, can be a very good way of approaching things....

            D Offline
            D Offline
            DzCode
            wrote on last edited by DzCode
            #5

            @JonB We have checkboxes and also we have colorboxes and colordialogs with item delegate. If I use another model, after sort, when I check a chekbox the colorbox in a different row is opened. This can be solved.

            But we have dropdown in the custom model. For example there are some special buttons in some rows which opens dropdown data or closes. Implementation of this will be hard

            1 Reply Last reply
            0
            • D Offline
              D Offline
              DzCode
              wrote on last edited by
              #6

              I am still looking for a better solution for this problem to make it with only one proxy model

              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