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. QAbstractProxyModel use with QTreeView

QAbstractProxyModel use with QTreeView

Scheduled Pinned Locked Moved Solved General and Desktop
c++subclassingtreeview modelproxy model
8 Posts 3 Posters 599 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
    SergeyK12
    wrote on last edited by SergeyK12
    #1

    Hi. Im trying to do the following exercise:
    Proxy QStandardItemModel into tree representation. First column is a roots for other columns. But Proxy subclassing unexpectedly undocumented and difficult to understand (without doc or examples).

    All i got for now is i should properly define parent method (since i dont use internal pointers)

    class StandardTreeProxy : public QAbstractProxyModel {
    
        // QAbstractItemModel interface
    public:
        QModelIndex index(int row, int column, const QModelIndex &parent) const
        {
            return createIndex(row, column);
        }
    
        QModelIndex parent(const QModelIndex &child) const
        {
            auto sourceIndex = mapToSource(child);
            auto proxyIndex = mapFromSource(sourceModel()->index(sourceIndex.row(), 0));
    
            if(child.row() == proxyIndex.row()) {
                return QModelIndex();
            }
    
            return proxyIndex;
        }
    
        int rowCount(const QModelIndex &parent) const
        {
            return  sourceModel()->rowCount() * sourceModel()->columnCount();
        }
    
        int columnCount(const QModelIndex &parent) const { return 1; }
    
    
        // QAbstractProxyModel interface
    public:
        QModelIndex mapToSource(const QModelIndex &proxyIndex) const
        {
            int row = std::round(proxyIndex.row() / sourceModel()->columnCount());
            int col = proxyIndex.row() % sourceModel()->columnCount();
            return sourceModel()->index(row, col);
        }
    
    
        QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
        {
            int row = sourceModel()->columnCount() * sourceIndex.row() + sourceIndex.column();
            int col = 0;
    
            if(row == 0) {
                return index(row, col, QModelIndex());
            }
    
            return index(row, col, createIndex(0, 0));
        }
    };
    

    original model
    93749a39-3259-40d4-a388-e9177280177c-image.png
    and proxy
    84f05708-b310-4dd1-ad04-a20f7e5639d1-image.png
    Im trying this, but all i got is columnts placed in a rows.
    Is it possible?
    Should i owerride another method from proxy?

    Christian EhrlicherC 1 Reply Last reply
    0
    • S SergeyK12

      @Christian-Ehrlicher
      Sorry, i cant find a way to show this:
      35b49de9-3c39-462e-a687-5ed2ce2a9c67-image.png
      as a tree
      b1a648c7-1756-4f9c-8658-91f2e3c5e511-image.png
      without proxy
      Possibly a should store data other way or use roles?

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

      @SergeyK12
      Are you aware that in a QStandardItemModel you can create a parent-child hierarchy? E.g. start from https://doc.qt.io/qt-6/qstandarditemmodel.html#details and QStandardItemModel::insertRow(int row, const QModelIndex &parent = QModelIndex()) etc.

      So why don't you store your model like that if it's hierarchical?

      Unless you mean you start with a QStandardItemModel which is flat and multi-column like the first one, for whatever reason, and want to display that in the second way. For that yes a proxy like yours would be good.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SergeyK12
        wrote on last edited by SergeyK12
        #2

        I found out, that rowCount should return count for child row.
        So it should be like this

        int rowCount(const QModelIndex &parent) const
        {
           if(!parent.isValid()) {
               return sourceModel()->rowCount();
           }
           return  sourceModel()->columnCount() - 1;
        }
        

        which reveal problems with parents ( now it only 1 row in a view, all paret idx is invalid)

        1 Reply Last reply
        0
        • S SergeyK12

          Hi. Im trying to do the following exercise:
          Proxy QStandardItemModel into tree representation. First column is a roots for other columns. But Proxy subclassing unexpectedly undocumented and difficult to understand (without doc or examples).

          All i got for now is i should properly define parent method (since i dont use internal pointers)

          class StandardTreeProxy : public QAbstractProxyModel {
          
              // QAbstractItemModel interface
          public:
              QModelIndex index(int row, int column, const QModelIndex &parent) const
              {
                  return createIndex(row, column);
              }
          
              QModelIndex parent(const QModelIndex &child) const
              {
                  auto sourceIndex = mapToSource(child);
                  auto proxyIndex = mapFromSource(sourceModel()->index(sourceIndex.row(), 0));
          
                  if(child.row() == proxyIndex.row()) {
                      return QModelIndex();
                  }
          
                  return proxyIndex;
              }
          
              int rowCount(const QModelIndex &parent) const
              {
                  return  sourceModel()->rowCount() * sourceModel()->columnCount();
              }
          
              int columnCount(const QModelIndex &parent) const { return 1; }
          
          
              // QAbstractProxyModel interface
          public:
              QModelIndex mapToSource(const QModelIndex &proxyIndex) const
              {
                  int row = std::round(proxyIndex.row() / sourceModel()->columnCount());
                  int col = proxyIndex.row() % sourceModel()->columnCount();
                  return sourceModel()->index(row, col);
              }
          
          
              QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
              {
                  int row = sourceModel()->columnCount() * sourceIndex.row() + sourceIndex.column();
                  int col = 0;
          
                  if(row == 0) {
                      return index(row, col, QModelIndex());
                  }
          
                  return index(row, col, createIndex(0, 0));
              }
          };
          

          original model
          93749a39-3259-40d4-a388-e9177280177c-image.png
          and proxy
          84f05708-b310-4dd1-ad04-a20f7e5639d1-image.png
          Im trying this, but all i got is columnts placed in a rows.
          Is it possible?
          Should i owerride another method from proxy?

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

          @SergeyK12 said in QAbstractProxyModel use with QTreeView:

          Proxy QStandardItemModel into tree representation.

          Why? There is no need for a proxy here at all.

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

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SergeyK12
            wrote on last edited by
            #4

            Im not familiar with qt models and proxy, so i found an answer on stackoverflow which stand that proxy is a proper way to do things. I thought its a good point to understand a basic about proxies.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SergeyK12
              wrote on last edited by
              #5

              I suppose that mapping function is incorrect (since it direct mapping, without tree structure). QModelIndex::parent crash the app.

                  QModelIndex mapToSource(const QModelIndex &proxyIndex) const
                  {
                      int row = std::round(proxyIndex.row() / sourceModel()->columnCount());
                      int col = proxyIndex.row() % sourceModel()->columnCount();
                      return sourceModel()->index(row, col);
                  }
              
              
                  QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
                  {
                      int row = sourceModel()->columnCount() * sourceIndex.row() + sourceIndex.column();
                      int col = 0;
              
                      if(row == 0) {
                          return index(row, col, QModelIndex());
                      }
              
                      return index(row, col, createIndex(0, 0));
                  }
              
              1 Reply Last reply
              0
              • Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                I still don't understand what you're trying to achieve - QStandardItemModel can be used in a QTreeView without any problems. So why trying to create a proxy model for this then? What's the gain?

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

                S 1 Reply Last reply
                1
                • Christian EhrlicherC Christian Ehrlicher

                  I still don't understand what you're trying to achieve - QStandardItemModel can be used in a QTreeView without any problems. So why trying to create a proxy model for this then? What's the gain?

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

                  @Christian-Ehrlicher
                  Sorry, i cant find a way to show this:
                  35b49de9-3c39-462e-a687-5ed2ce2a9c67-image.png
                  as a tree
                  b1a648c7-1756-4f9c-8658-91f2e3c5e511-image.png
                  without proxy
                  Possibly a should store data other way or use roles?

                  JonBJ 1 Reply Last reply
                  0
                  • S SergeyK12

                    @Christian-Ehrlicher
                    Sorry, i cant find a way to show this:
                    35b49de9-3c39-462e-a687-5ed2ce2a9c67-image.png
                    as a tree
                    b1a648c7-1756-4f9c-8658-91f2e3c5e511-image.png
                    without proxy
                    Possibly a should store data other way or use roles?

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

                    @SergeyK12
                    Are you aware that in a QStandardItemModel you can create a parent-child hierarchy? E.g. start from https://doc.qt.io/qt-6/qstandarditemmodel.html#details and QStandardItemModel::insertRow(int row, const QModelIndex &parent = QModelIndex()) etc.

                    So why don't you store your model like that if it's hierarchical?

                    Unless you mean you start with a QStandardItemModel which is flat and multi-column like the first one, for whatever reason, and want to display that in the second way. For that yes a proxy like yours would be good.

                    1 Reply Last reply
                    0
                    • S SergeyK12 has marked this topic as solved on

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved