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. QTreeView, how to get the scrollbars when resizing if we don't use ElideMode?

QTreeView, how to get the scrollbars when resizing if we don't use ElideMode?

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 4 Posters 4.0k 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.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by
    #1

    Hi,
    I've a QTreeView on the left Side of a QSplitter and I don't understand how / when the Horinzontal ScrollBars arrives when I'm decreasing the width of the QTreeView.

    By default there is the ElideMode when we reduce the view but I've removed it using a deleage:

    void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        QStandardItem *item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
        if (!item)
            return;
    
        QStyleOptionViewItem myOption = option;
        myOption.textElideMode = Qt::ElideNone;
        QStyledItemDelegate::paint(painter, myOption, index);
    }
    

    So now the scrollbars are not kicking in as soon as a part of the view is hidden but only when arrive to the Icons of my Items.

    Any idea how I could makes them arrive as soon as some text is hidden. In other words I'd like that the size of the View should always take all the Items in consideration and that resize itself when I expand or collapse some of them.

    Thanks in advance :)

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

      Hi,

      Did you also reimplement the sizeHint method ?

      Hope it helps

      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
      • mbruelM Offline
        mbruelM Offline
        mbruel
        wrote on last edited by mbruel
        #3

        on the delegate? yes but it doesn't seem to have any effect on the horizontal scrollbar of the QTreeView.
        The behaviour stays the same...

        QSize TreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
        {
            QSize size = QStyledItemDelegate::sizeHint(option, index);
            return QSize(500, 18);
        }
        

        only the hight seems to have an impact on the TreeView. (I've certain row larger (bigger icon and font bold))

        By looking again, it looks like the horizontal ScrollBar kicks in only when my first row starts to not have enough space.
        Is there something to do to resize the QTreeView with the its content (a bit like the QTableWidget::resizeColumnsToContents ?)

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

          The resizeColumnToContent method is also available with QTreeView. It’s part of the base class.

          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
          2
          • mbruelM Offline
            mbruelM Offline
            mbruel
            wrote on last edited by
            #5

            yeah but it looks like it is only taking into account the columns of the first rows.
            I'm having a tree structure with 4 level of children from my first row.
            How could I make the Tree take those in consideration.
            I wouldn't mind to resize the QTreeView each time I insert a new Child cause this operation shouldn't happen so often.

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

              Can you post a minimal sample code so we have the same widgets to look at ?

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

              mbruelM 1 Reply Last reply
              0
              • mbruelM Offline
                mbruelM Offline
                mbruel
                wrote on last edited by mbruel
                #7

                ok I've done a simple example of my code:

                Here is tree.h

                #ifndef TREE_H
                #define TREE_H
                
                #include <QStandardItemModel>
                #include <QStyledItemDelegate>
                
                
                enum class TreeItemType {
                    TreeElementItem  = 0x1,
                    TreeTypeItem     = 0x10
                };
                
                class TreeItem : public QStandardItem
                {
                public:
                    TreeItem(const QString &txt, TreeItemType type = TreeItemType::TreeElementItem)
                        : QStandardItem(), _type(type), _txt(txt) {}
                    virtual ~TreeItem() = default;
                
                    QVariant data( int role = Qt::UserRole ) const override;
                    TreeItemType getType() const {return _type;}
                private:
                    const TreeItemType _type;
                    const QString      _txt;
                };
                
                
                
                class TreeItemDelegate : public QStyledItemDelegate
                {
                public:
                    TreeItemDelegate()  = default;
                    ~TreeItemDelegate() = default;
                
                    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
                    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
                };
                
                
                class TreeModel : public QStandardItemModel
                {
                    Q_OBJECT
                
                public:
                    TreeModel()  = default;
                    ~TreeModel() = default;
                
                    Qt::ItemFlags flags(const QModelIndex& index) const override;
                
                    void load();
                };
                
                #endif // TREE_H
                

                Tree.cpp

                #include "tree.h"
                
                QVariant TreeItem::data(int role) const
                {
                    switch (role) {
                    case Qt::DisplayRole:
                    {
                        QString msg(_txt);
                        if (_type == TreeItemType::TreeTypeItem)
                            msg += QString(" (%1)").arg(rowCount());
                        return msg;
                    }
                    default:
                        return QStandardItem::data(role);
                    }
                }
                
                void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                {
                    QStandardItem *item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
                    if (!item)
                        return;
                
                    QStyleOptionViewItem myOption = option;
                    myOption.textElideMode = Qt::ElideNone;
                
                    if (static_cast<TreeItem*>(item)->getType() == TreeItemType::TreeTypeItem)
                    {
                        myOption.font.setBold(true);
                        myOption.decorationSize = QSize(24,24);
                    }
                
                    QStyledItemDelegate::paint(painter, myOption, index);
                }
                
                QSize TreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
                {
                    QSize size = QStyledItemDelegate::sizeHint(option, index);
                
                    QStandardItem *item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
                    if (item)
                    {
                        if (static_cast<TreeItem*>(item)->getType() == TreeItemType::TreeTypeItem)
                            size.setHeight(26);
                        else
                            size.setHeight(18);
                    }
                
                    return size;
                }
                
                
                
                Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const
                {
                    QStandardItem *item = itemFromIndex(index);
                    if (!item)
                        return 0;
                
                    TreeItemType itemType = static_cast<TreeItemType>(item->data(Qt::UserRole).toInt());
                    if (itemType == TreeItemType::TreeTypeItem)
                        return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
                    else
                        return Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsEditable;
                }
                
                void TreeModel::load()
                {
                    TreeItem *project = new TreeItem("Project");
                    invisibleRootItem()->appendRow(project);
                
                    TreeItem *firstType = new TreeItem("First Type", TreeItemType::TreeTypeItem);
                    project->appendRow(firstType);
                
                    for (ushort i=0 ; i < 5 ; ++i)
                    {
                        TreeItem *someItem = new TreeItem(QString("Some Items number #%1").arg(i));
                        firstType->appendRow(someItem);
                    }
                
                    TreeItem *secondType = new TreeItem("Second Type a bit longer", TreeItemType::TreeTypeItem);
                    project->appendRow(secondType);
                
                }
                

                mainwindow.h

                #ifndef MAINWINDOW_H
                #define MAINWINDOW_H
                
                #include <QMainWindow>
                
                namespace Ui {
                class MainWindow;
                }
                
                class TreeModel;
                class QAbstractItemDelegate;
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    explicit MainWindow(QWidget *parent = 0);
                    ~MainWindow();
                
                private:
                    Ui::MainWindow        *_ui;
                    TreeModel             *_treeModel;
                    QAbstractItemDelegate *_treeItemDelegate;
                };
                
                #endif // MAINWINDOW_H
                

                and mainwindow.cpp

                #include "mainwindow.h"
                #include "ui_mainwindow.h"
                #include <QLabel>
                #include "tree.h"
                
                MainWindow::MainWindow(QWidget *parent) :
                    QMainWindow(parent),
                    _ui(new Ui::MainWindow), _treeModel(new TreeModel()), _treeItemDelegate(new TreeItemDelegate())
                {
                    _ui->setupUi(this);
                
                    QLabel *editor = new QLabel("<h3>Editor</h3>", this);
                    _ui->splitter->addWidget(editor);
                
                    _ui->splitter->setCollapsible(0, false);
                    _ui->splitter->setCollapsible(1, false);
                    _ui->splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
                
                
                    _ui->treeView->setModel(_treeModel);
                    if (_treeItemDelegate)
                        _ui->treeView->setItemDelegate(_treeItemDelegate);
                
                    _treeModel->load();
                }
                
                MainWindow::~MainWindow()
                {
                    delete _ui;
                }
                

                and the mainwindow.ui

                <?xml version="1.0" encoding="UTF-8"?>
                <ui version="4.0">
                 <class>MainWindow</class>
                 <widget class="QMainWindow" name="MainWindow">
                  <property name="geometry">
                   <rect>
                    <x>0</x>
                    <y>0</y>
                    <width>756</width>
                    <height>565</height>
                   </rect>
                  </property>
                  <property name="windowTitle">
                   <string>MainWindow</string>
                  </property>
                  <widget class="QWidget" name="centralWidget">
                   <widget class="QSplitter" name="splitter">
                    <property name="geometry">
                     <rect>
                      <x>10</x>
                      <y>10</y>
                      <width>661</width>
                      <height>491</height>
                     </rect>
                    </property>
                    <property name="orientation">
                     <enum>Qt::Horizontal</enum>
                    </property>
                    <widget class="QTreeView" name="treeView"/>
                   </widget>
                  </widget>
                  <widget class="QMenuBar" name="menuBar">
                   <property name="geometry">
                    <rect>
                     <x>0</x>
                     <y>0</y>
                     <width>756</width>
                     <height>19</height>
                    </rect>
                   </property>
                   <widget class="QMenu" name="menuFile">
                    <property name="title">
                     <string>File</string>
                    </property>
                   </widget>
                   <widget class="QMenu" name="menuUndoStack">
                    <property name="title">
                     <string>UndoStack</string>
                    </property>
                    <addaction name="actionUndo"/>
                    <addaction name="actionRedo"/>
                   </widget>
                   <addaction name="menuFile"/>
                   <addaction name="menuUndoStack"/>
                  </widget>
                  <widget class="QToolBar" name="mainToolBar">
                   <attribute name="toolBarArea">
                    <enum>TopToolBarArea</enum>
                   </attribute>
                   <attribute name="toolBarBreak">
                    <bool>false</bool>
                   </attribute>
                  </widget>
                  <widget class="QStatusBar" name="statusBar"/>
                  <action name="actionUndo">
                   <property name="text">
                    <string>Undo</string>
                   </property>
                  </action>
                  <action name="actionRedo">
                   <property name="text">
                    <string>Redo</string>
                   </property>
                  </action>
                 </widget>
                 <layoutdefault spacing="6" margin="11"/>
                 <resources/>
                 <connections/>
                </ui>
                

                My problem is that I don't know how I could make the horizontal scrollbar kicks in as soon as one Item of the TreeView is not fully visible.
                alt text

                Any idea how I could achieve it? I guess it is something that should be simple...

                PS: another problem I have is that my QSlider is not taking the full area of my window. If I go fullscreen, the TreeView is not resizing.

                jsulmJ 1 Reply Last reply
                0
                • mbruelM mbruel

                  ok I've done a simple example of my code:

                  Here is tree.h

                  #ifndef TREE_H
                  #define TREE_H
                  
                  #include <QStandardItemModel>
                  #include <QStyledItemDelegate>
                  
                  
                  enum class TreeItemType {
                      TreeElementItem  = 0x1,
                      TreeTypeItem     = 0x10
                  };
                  
                  class TreeItem : public QStandardItem
                  {
                  public:
                      TreeItem(const QString &txt, TreeItemType type = TreeItemType::TreeElementItem)
                          : QStandardItem(), _type(type), _txt(txt) {}
                      virtual ~TreeItem() = default;
                  
                      QVariant data( int role = Qt::UserRole ) const override;
                      TreeItemType getType() const {return _type;}
                  private:
                      const TreeItemType _type;
                      const QString      _txt;
                  };
                  
                  
                  
                  class TreeItemDelegate : public QStyledItemDelegate
                  {
                  public:
                      TreeItemDelegate()  = default;
                      ~TreeItemDelegate() = default;
                  
                      void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
                      QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
                  };
                  
                  
                  class TreeModel : public QStandardItemModel
                  {
                      Q_OBJECT
                  
                  public:
                      TreeModel()  = default;
                      ~TreeModel() = default;
                  
                      Qt::ItemFlags flags(const QModelIndex& index) const override;
                  
                      void load();
                  };
                  
                  #endif // TREE_H
                  

                  Tree.cpp

                  #include "tree.h"
                  
                  QVariant TreeItem::data(int role) const
                  {
                      switch (role) {
                      case Qt::DisplayRole:
                      {
                          QString msg(_txt);
                          if (_type == TreeItemType::TreeTypeItem)
                              msg += QString(" (%1)").arg(rowCount());
                          return msg;
                      }
                      default:
                          return QStandardItem::data(role);
                      }
                  }
                  
                  void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                  {
                      QStandardItem *item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
                      if (!item)
                          return;
                  
                      QStyleOptionViewItem myOption = option;
                      myOption.textElideMode = Qt::ElideNone;
                  
                      if (static_cast<TreeItem*>(item)->getType() == TreeItemType::TreeTypeItem)
                      {
                          myOption.font.setBold(true);
                          myOption.decorationSize = QSize(24,24);
                      }
                  
                      QStyledItemDelegate::paint(painter, myOption, index);
                  }
                  
                  QSize TreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
                  {
                      QSize size = QStyledItemDelegate::sizeHint(option, index);
                  
                      QStandardItem *item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
                      if (item)
                      {
                          if (static_cast<TreeItem*>(item)->getType() == TreeItemType::TreeTypeItem)
                              size.setHeight(26);
                          else
                              size.setHeight(18);
                      }
                  
                      return size;
                  }
                  
                  
                  
                  Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const
                  {
                      QStandardItem *item = itemFromIndex(index);
                      if (!item)
                          return 0;
                  
                      TreeItemType itemType = static_cast<TreeItemType>(item->data(Qt::UserRole).toInt());
                      if (itemType == TreeItemType::TreeTypeItem)
                          return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
                      else
                          return Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsEditable;
                  }
                  
                  void TreeModel::load()
                  {
                      TreeItem *project = new TreeItem("Project");
                      invisibleRootItem()->appendRow(project);
                  
                      TreeItem *firstType = new TreeItem("First Type", TreeItemType::TreeTypeItem);
                      project->appendRow(firstType);
                  
                      for (ushort i=0 ; i < 5 ; ++i)
                      {
                          TreeItem *someItem = new TreeItem(QString("Some Items number #%1").arg(i));
                          firstType->appendRow(someItem);
                      }
                  
                      TreeItem *secondType = new TreeItem("Second Type a bit longer", TreeItemType::TreeTypeItem);
                      project->appendRow(secondType);
                  
                  }
                  

                  mainwindow.h

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  
                  namespace Ui {
                  class MainWindow;
                  }
                  
                  class TreeModel;
                  class QAbstractItemDelegate;
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  public:
                      explicit MainWindow(QWidget *parent = 0);
                      ~MainWindow();
                  
                  private:
                      Ui::MainWindow        *_ui;
                      TreeModel             *_treeModel;
                      QAbstractItemDelegate *_treeItemDelegate;
                  };
                  
                  #endif // MAINWINDOW_H
                  

                  and mainwindow.cpp

                  #include "mainwindow.h"
                  #include "ui_mainwindow.h"
                  #include <QLabel>
                  #include "tree.h"
                  
                  MainWindow::MainWindow(QWidget *parent) :
                      QMainWindow(parent),
                      _ui(new Ui::MainWindow), _treeModel(new TreeModel()), _treeItemDelegate(new TreeItemDelegate())
                  {
                      _ui->setupUi(this);
                  
                      QLabel *editor = new QLabel("<h3>Editor</h3>", this);
                      _ui->splitter->addWidget(editor);
                  
                      _ui->splitter->setCollapsible(0, false);
                      _ui->splitter->setCollapsible(1, false);
                      _ui->splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
                  
                  
                      _ui->treeView->setModel(_treeModel);
                      if (_treeItemDelegate)
                          _ui->treeView->setItemDelegate(_treeItemDelegate);
                  
                      _treeModel->load();
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      delete _ui;
                  }
                  

                  and the mainwindow.ui

                  <?xml version="1.0" encoding="UTF-8"?>
                  <ui version="4.0">
                   <class>MainWindow</class>
                   <widget class="QMainWindow" name="MainWindow">
                    <property name="geometry">
                     <rect>
                      <x>0</x>
                      <y>0</y>
                      <width>756</width>
                      <height>565</height>
                     </rect>
                    </property>
                    <property name="windowTitle">
                     <string>MainWindow</string>
                    </property>
                    <widget class="QWidget" name="centralWidget">
                     <widget class="QSplitter" name="splitter">
                      <property name="geometry">
                       <rect>
                        <x>10</x>
                        <y>10</y>
                        <width>661</width>
                        <height>491</height>
                       </rect>
                      </property>
                      <property name="orientation">
                       <enum>Qt::Horizontal</enum>
                      </property>
                      <widget class="QTreeView" name="treeView"/>
                     </widget>
                    </widget>
                    <widget class="QMenuBar" name="menuBar">
                     <property name="geometry">
                      <rect>
                       <x>0</x>
                       <y>0</y>
                       <width>756</width>
                       <height>19</height>
                      </rect>
                     </property>
                     <widget class="QMenu" name="menuFile">
                      <property name="title">
                       <string>File</string>
                      </property>
                     </widget>
                     <widget class="QMenu" name="menuUndoStack">
                      <property name="title">
                       <string>UndoStack</string>
                      </property>
                      <addaction name="actionUndo"/>
                      <addaction name="actionRedo"/>
                     </widget>
                     <addaction name="menuFile"/>
                     <addaction name="menuUndoStack"/>
                    </widget>
                    <widget class="QToolBar" name="mainToolBar">
                     <attribute name="toolBarArea">
                      <enum>TopToolBarArea</enum>
                     </attribute>
                     <attribute name="toolBarBreak">
                      <bool>false</bool>
                     </attribute>
                    </widget>
                    <widget class="QStatusBar" name="statusBar"/>
                    <action name="actionUndo">
                     <property name="text">
                      <string>Undo</string>
                     </property>
                    </action>
                    <action name="actionRedo">
                     <property name="text">
                      <string>Redo</string>
                     </property>
                    </action>
                   </widget>
                   <layoutdefault spacing="6" margin="11"/>
                   <resources/>
                   <connections/>
                  </ui>
                  

                  My problem is that I don't know how I could make the horizontal scrollbar kicks in as soon as one Item of the TreeView is not fully visible.
                  alt text

                  Any idea how I could achieve it? I guess it is something that should be simple...

                  PS: another problem I have is that my QSlider is not taking the full area of my window. If I go fullscreen, the TreeView is not resizing.

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @mbruel said in QTreeView, how to get the scrollbars when resizing if we don't use ElideMode?:

                  QSlider is not taking the full area of my window

                  Is your QSlider in a layout?

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • mbruelM Offline
                    mbruelM Offline
                    mbruel
                    wrote on last edited by
                    #9

                    Well I'm not sure...
                    I'm using Qt Creator designer. In the Central Widget I've added my TreeView and another Widget then I've selected both and click on "Layout Horizontally in a Splitter".
                    I was thinking the Splitter would be the layout of the MainWindow but I guess not...

                    You can find the Qt Project here

                    jsulmJ 1 Reply Last reply
                    0
                    • mbruelM mbruel

                      Well I'm not sure...
                      I'm using Qt Creator designer. In the Central Widget I've added my TreeView and another Widget then I've selected both and click on "Layout Horizontally in a Splitter".
                      I was thinking the Splitter would be the layout of the MainWindow but I guess not...

                      You can find the Qt Project here

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @mbruel No, the splitter is the "layout" of the two widgets. Press somewhere in your central widget and press "Lay Out in a Grid".

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      mbruelM 1 Reply Last reply
                      1
                      • jsulmJ jsulm

                        @mbruel No, the splitter is the "layout" of the two widgets. Press somewhere in your central widget and press "Lay Out in a Grid".

                        mbruelM Offline
                        mbruelM Offline
                        mbruel
                        wrote on last edited by
                        #11

                        @jsulm
                        ok thanks, yes, it solves this global size issue.
                        Any idea on the original issue: how to make the horizontal scrollbar of the TreeView kicks in when some of its items are not fully visible?

                        1 Reply Last reply
                        0
                        • SGaistS SGaist

                          Can you post a minimal sample code so we have the same widgets to look at ?

                          mbruelM Offline
                          mbruelM Offline
                          mbruel
                          wrote on last edited by
                          #12

                          @SGaist
                          Any ideas for this issue?
                          I've posted the code and a zip of the project.

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            mpergand
                            wrote on last edited by mpergand
                            #13

                            @mbruel said in QTreeView, how to get the scrollbars when resizing if we don't use ElideMode?:

                            In Designer, uncheck "headerStretchLastSection"

                            mbruelM 1 Reply Last reply
                            1
                            • M mpergand

                              @mbruel said in QTreeView, how to get the scrollbars when resizing if we don't use ElideMode?:

                              In Designer, uncheck "headerStretchLastSection"

                              mbruelM Offline
                              mbruelM Offline
                              mbruel
                              wrote on last edited by
                              #14

                              @mpergand
                              Well this make it worst. My items are all the time truncated even when there is space in the QTreeView.
                              alt text

                              It seems the size of the viewport is the one of the header? how could the size of the longest row? and set it to be this? I found it strange that there is not an option to do this automatically...

                              1 Reply Last reply
                              0
                              • mbruelM Offline
                                mbruelM Offline
                                mbruel
                                wrote on last edited by
                                #15

                                It seems that it is the header DefaultSectionSize that defines when the scrollbar will kicks in.
                                I've tried to use the visualRect of my items but I'm getting a invalid one for all the items except the first one...

                                MainWindow::MainWindow(QWidget *parent) :
                                    QMainWindow(parent),
                                    _ui(new Ui::MainWindow), _treeModel(new TreeModel()), _treeItemDelegate(new TreeItemDelegate())
                                {
                                    _ui->setupUi(this);
                                ....
                                
                                    int maxWidth = 0;
                                    _setTreeViewMaxWith(maxWidth);
                                
                                    _ui->treeView->header()->setDefaultSectionSize(maxWidth);
                                }
                                
                                #include <QDebug>
                                void MainWindow::_setTreeViewMaxWith(int &maxWidth, QModelIndex parent)
                                {
                                    for(int r = 0; r < _treeModel->rowCount(parent); ++r)
                                    {
                                        QModelIndex index = _treeModel->index(r, 0, parent);
                                        int width = _ui->treeView->visualRect(index).width();
                                qDebug() << "width row " << r << " : "   << width;
                                        if (width > maxWidth)
                                            maxWidth = width;
                                
                                        if( _treeModel->hasChildren(index) )
                                            _setTreeViewMaxWith(maxWidth, index);
                                    }
                                }
                                

                                Here is the output:
                                width row 0 : 180
                                width row 0 : 0
                                width row 0 : 0
                                width row 1 : 0
                                width row 2 : 0
                                width row 3 : 0
                                width row 4 : 0
                                width row 1 : 0

                                1 Reply Last reply
                                0
                                • M Offline
                                  M Offline
                                  mpergand
                                  wrote on last edited by mpergand
                                  #16
                                  _ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
                                  

                                  Work well with elideMode ...
                                  Infinite loop detected :)

                                  Well, the only solution seems to resize the column yourself, you can memorize the larger item in TreeItemDelegate::sizeHint
                                  and set the column width accordingly.

                                  mbruelM 2 Replies Last reply
                                  1
                                  • M mpergand
                                    _ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
                                    

                                    Work well with elideMode ...
                                    Infinite loop detected :)

                                    Well, the only solution seems to resize the column yourself, you can memorize the larger item in TreeItemDelegate::sizeHint
                                    and set the column width accordingly.

                                    mbruelM Offline
                                    mbruelM Offline
                                    mbruel
                                    wrote on last edited by
                                    #17

                                    @mpergand
                                    Cool, thanks, good advise :)
                                    You're right, instead of resizing the header, I can just resize the first column.
                                    What I've done is that my Delegate emit a signal in SizeHint when the size max increase. My MainWindow catch the signal and resize the column accordingly taking the indent of the index in consideration...
                                    This works but I'm quite surprised that we've to do it manually and that the functionality is not offered by the QTreeView directly.

                                    Here is my code for the people interested

                                    QSize TreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
                                    {
                                        QStyleOptionViewItem myOption = option;
                                        myOption.textElideMode = Qt::ElideNone;
                                    
                                        QStandardItem *item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
                                        if (static_cast<TreeItem*>(item)->getType() == TreeItemType::TreeTypeItem)
                                        {
                                            myOption.font.setBold(true);
                                            myOption.decorationSize = QSize(24,24);
                                        }
                                    
                                        QSize size = QStyledItemDelegate::sizeHint(myOption, index);
                                        if (size.width() > _maxWidth)
                                        {
                                            _maxWidth = size.width();
                                            emit maxWidthIncreased(_maxWidth, index);
                                        }
                                    
                                        if (item)
                                        {
                                            if (static_cast<TreeItem*>(item)->getType() == TreeItemType::TreeTypeItem)
                                                size.setHeight(26);
                                            else
                                                size.setHeight(18);
                                        }
                                    
                                        return size;
                                    }
                                    

                                    and in MainWindow:

                                    void MainWindow::handleTreeViewMaxWidthChanged(int maxWidth, QModelIndex index)
                                    {
                                        int indent = _ui->treeView->indentation();
                                        while (index.parent().isValid())
                                        {
                                            indent += _ui->treeView->indentation();
                                            index = index.parent();
                                        }
                                    
                                        qDebug() << "Max width from Delegate: " << maxWidth << ", indent: " << indent;
                                        _ui->treeView->setColumnWidth(0, maxWidth+indent);
                                    }
                                    

                                    PS: for this to work, TreeItemDelegate::_maxWidth is mutable and the signal is const

                                    class TreeItemDelegate : public QStyledItemDelegate
                                    {
                                        Q_OBJECT
                                    ...
                                    signals:
                                        void maxWidthIncreased(int maxSize, QModelIndex index) const;
                                    
                                    private:
                                        mutable int _maxWidth;
                                    };
                                    
                                    1 Reply Last reply
                                    0
                                    • M mpergand
                                      _ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
                                      

                                      Work well with elideMode ...
                                      Infinite loop detected :)

                                      Well, the only solution seems to resize the column yourself, you can memorize the larger item in TreeItemDelegate::sizeHint
                                      and set the column width accordingly.

                                      mbruelM Offline
                                      mbruelM Offline
                                      mbruel
                                      wrote on last edited by
                                      #18

                                      @mpergand said in QTreeView, how to get the scrollbars when resizing if we don't use ElideMode?:

                                      Infinite loop detected :)

                                      where would you see an infinite loop?

                                      1 Reply Last reply
                                      0
                                      • mbruelM Offline
                                        mbruelM Offline
                                        mbruel
                                        wrote on last edited by
                                        #19

                                        Following another this other thread about customizing delegates with the display of the icons, here is a more efficient version of this one:

                                        QSize TreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
                                        {
                                            QSize size = QStyledItemDelegate::sizeHint(option, index);
                                            if (size.width() > _maxWidth)
                                            {
                                                _maxWidth = size.width();
                                                emit maxWidthIncreased(_maxWidth, index);
                                            }
                                            return size;
                                        }
                                        
                                        void TreeItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
                                        {
                                            QStyledItemDelegate::initStyleOption(option, index);
                                            option->textElideMode = Qt::ElideNone;
                                        
                                            TreeItem *item = nullptr;
                                            if (_useProxy)
                                                item = static_cast<const TreeProxyModel*>(index.model())->itemFromIndex(index);
                                            else
                                                item = static_cast<const TreeModel*>(index.model())->itemFromIndex(index);
                                        
                                            if (item && static_cast<TreeItem*>(item)->isRootItem())
                                            {
                                        //        option->palette.setColor(QPalette::Normal, QPalette::Text,Qt::blue);
                                                option->font.setBold(true);
                                                option->decorationSize = QSize(24,24);
                                            }
                                        }
                                        

                                        No need to override the paint method but instead the protected initStyleOption

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

                                          Thanks for the feedback !

                                          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

                                          • Login

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