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
QtWS25 Last Chance

QAbstractProxyModel use with QTreeView

Scheduled Pinned Locked Moved Solved General and Desktop
c++subclassingtreeview modelproxy model
8 Posts 3 Posters 589 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 Online
          Christian EhrlicherC Online
          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 Online
                Christian EhrlicherC Online
                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