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. Get geometry of a row in QTreeView
Forum Updated to NodeBB v4.3 + New Features

Get geometry of a row in QTreeView

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 915 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.
  • L Offline
    L Offline
    Lurkki
    wrote on last edited by
    #1

    I want to be able to make an editor in my custom delegate span all columns on demand. I'm trying to do it with a subclassed QStyledItemDelegate and QTreeView as follows:

        // Subclassed QTreeView
        QRect rowGeometry(const QModelIndex &index) {
            int indent = (index.column() + 1) * indentation();
            int firstSection = header()->logicalIndex(0);
            int lastSection = header()->logicalIndex(header()->count() - 1);
            int left = header()->sectionViewportPosition(firstSection);
            int right = header()->sectionViewportPosition(lastSection) + header()->sectionSize(lastSection);
    
            left += indent;
    
            QPoint rowTopLeft(rect().topLeft().x() + indent, rect().topLeft().y() + rowHeight(index) * (index.row() + 1);
            QRect rec(rect().topLeft(), QSize(right - left, rowHeight(index)));
            return rec;
        }
    
        // Subclassed QStyledItemDelegate
        void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
            editor->setGeometry(m_subclassedTreeView->rowGeometry(index));
        }
    

    The result is that the editor doesn't follow the indentation, and is always on row 0. I'm also open to accomplishing this some other way.

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

      Hi,

      Can you provide a minimal compilable example that shows that behaviour ?

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

      1 Reply Last reply
      0
      • L Offline
        L Offline
        Lurkki
        wrote on last edited by
        #3
        #include <QTreeView>
        #include <QHeaderView>
        #include <QStyledItemDelegate>
        #include <QStandardItemModel>
        #include <QVBoxLayout>
        
        class ExpandableTreeView : public QTreeView {
        public:
            ExpandableTreeView(QWidget *parent = nullptr) : QTreeView(parent) {
            }
            void setExpandableIndex(const QModelIndex &index) {m_expandableIndex = index;}
            QRect rowGeometry(const QModelIndex &index) {
                int indent = (index.column() + 1) * indentation();
                int firstSection = header()->logicalIndex(0);
                int lastSection = header()->logicalIndex(header()->count() - 1);
                int left = header()->sectionViewportPosition(firstSection);
                int right = header()->sectionViewportPosition(lastSection) + header()->sectionSize(lastSection);
        
                left += indent;
        
                QPoint rowTopLeft(rect().topLeft().x() + indent, rect().topLeft().y() + rowHeight(index));
                QRect rec(rect().topLeft(), QSize(right - left, rowHeight(index)));
                return rec;
            }
        private:
            QModelIndex m_expandableIndex;
        };
        
        class ExpandableDelegate : public QStyledItemDelegate {
        public:
            ExpandableDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
            QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
                return QStyledItemDelegate::sizeHint(option, index);
            }
            void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
                QRect geo = m_eview->rowGeometry(index);
                editor->setGeometry(geo);
            }
            void setExpandableIndex(const QModelIndex &index) {m_expandableIndex = index;}
            void setExpandableTreeView(ExpandableTreeView *view) {m_eview = view;}
        private:
            QModelIndex m_expandableIndex;
            ExpandableTreeView *m_eview;
        };
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
        {
            auto central = new QWidget;
        
            auto lo = new QVBoxLayout;
        
            auto model = new QStandardItemModel;
        
            auto root = model->invisibleRootItem();
        
            auto view = new ExpandableTreeView;
        
            QList <QStandardItem*> rowItems;
            for (int i = 0; i < 3; i++) {
                auto item = new QStandardItem;
                item->setText(QString::number(i));
                rowItems.append(item);
        
                auto i2 = new QStandardItem;
                i2->setText(QString::number(i + 1));
                rowItems.append(i2);
        
        
                root->appendRow(rowItems);
                rowItems.clear();
            }
            auto delegate = new ExpandableDelegate;
            delegate->setExpandableTreeView(view);
        
            view->setItemDelegate(delegate);
            view->setModel(model);
        
            lo->addWidget(view);
        
            central->setLayout(lo);
        
            setCentralWidget(central);
        
            connect(view, &ExpandableTreeView::activated, [=](const QModelIndex &index) {
                delegate->setExpandableIndex(index);
            });
        }
        
        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          I think this could be easily solved by just using visualRect() in the delegate:

          void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &, const QModelIndex &index) const {
              const int maxCol = index.model()->columnCount(index.parent());
              QRect tempRect = m_subclassedTreeView->visualRect(index.model()->index(index.row(),0,index.parent()));
              int top = tempRect.top();
              int left = tempRect.left();
              int bottom = tempRect.bottom();
              int right= tempRect.right();
              for(int i = 1;i<maxCol ;++i){
                  tempRect =m_subclassedTreeView->visualRect(index.model()->index(index.row(),i,index.parent()));
                  if(tempRect.top()<top)
                      top = tempRect.top();
                  if(Q_UNLIKELY(tempRect.left()<left))
                      left= tempRect.left();
                  if(tempRect.bottom()>bottom)
                      bottom = tempRect.bottom();
                  if(Q_LIKELY(tempRect.right()>right))
                      right= tempRect.right();
              }
              editor->setGeometry(QRect(QPoint(top,left),QPoint(bottom,right)));
          }
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          L 1 Reply Last reply
          2
          • VRoninV VRonin

            I think this could be easily solved by just using visualRect() in the delegate:

            void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &, const QModelIndex &index) const {
                const int maxCol = index.model()->columnCount(index.parent());
                QRect tempRect = m_subclassedTreeView->visualRect(index.model()->index(index.row(),0,index.parent()));
                int top = tempRect.top();
                int left = tempRect.left();
                int bottom = tempRect.bottom();
                int right= tempRect.right();
                for(int i = 1;i<maxCol ;++i){
                    tempRect =m_subclassedTreeView->visualRect(index.model()->index(index.row(),i,index.parent()));
                    if(tempRect.top()<top)
                        top = tempRect.top();
                    if(Q_UNLIKELY(tempRect.left()<left))
                        left= tempRect.left();
                    if(tempRect.bottom()>bottom)
                        bottom = tempRect.bottom();
                    if(Q_LIKELY(tempRect.right()>right))
                        right= tempRect.right();
                }
                editor->setGeometry(QRect(QPoint(top,left),QPoint(bottom,right)));
            }
            
            L Offline
            L Offline
            Lurkki
            wrote on last edited by
            #5

            @VRonin That works though I had to change editor->setGeometry(QRect(QPoint(top, left),QPoint(bottom, right))); to editor->setGeometry(QRect(QPoint(left, top),QPoint(right, bottom)));

            1 Reply Last reply
            2

            • Login

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