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. can't manage to resize column of QTreeView Automatically
Forum Updated to NodeBB v4.3 + New Features

can't manage to resize column of QTreeView Automatically

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 988 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.
  • O Offline
    O Offline
    olivier_subatech
    wrote on 21 Mar 2024, 13:16 last edited by
    #1

    Hi there,
    I've bee struggling with these for a while and I just can't manage to make this work... I'd like the first column of my QTreeView to automatically resize to fit the content of the folder it displays and, it does not work.
    Can you please help me on this one.
    thank you very much for your help.

    Olivier

    #include "file_system_navigator.hxx"
    #include <QDebug>
    #include <string>
    
    file_system_navigator::file_system_navigator(QWidget* parent) :
      QWidget{parent},                                //
      path{""},                                       //
      label{new QLabel(tr("&current folder"), this)}, //
      _directory_line{new QLineEdit(this)},           //
      _open_button{new QPushButton("open...", this)}, //
      _model{new QFileSystemModel(this)},             //
      _view{new QTreeView(this)},                     //
      _menu{new QMenu(this)}
    {
      create_layout();
      init_widgets();
      create_connections();
      create_actions();
      create_menus();
    }
    
    file_system_navigator::~file_system_navigator() {}
    
    QString file_system_navigator::get_last_path()
    {
      QSettings settings("org", "soft");
      return settings.value("last_config_path").toString();
    }
    
    QString file_system_navigator::set_last_path(QString new_path)
    {
      QSettings settings("org", "soft");
      settings.setValue("last_config_path", new_path);
      return settings.value("last_config_path").toString();
    }
    
    
    void file_system_navigator::init_widgets()
    {
      label->setBuddy(_open_button);
    
      QString last_path = get_last_path();
      _directory_line->setText(last_path);
    
      // _model
      _model->setNameFilterDisables(true);
      _model->setFilter(QDir::AllEntries | QDir::AllDirs | QDir::NoSymLinks);
      // tree
      _view->setModel(_model);
      _view->setSortingEnabled(true);
      _view->sortByColumn(0, Qt::SortOrder::AscendingOrder);
      _view->setAlternatingRowColors(true);
      _view->setExpandsOnDoubleClick(false);
      _view->setItemsExpandable(false);
      _view->setSelectionMode(QTreeView::ContiguousSelection);
      // _view->hideColumn(2); // type
      _view->repaint();
    
      _model->setRootPath(last_path);
      _view->setRootIndex(_model->index(last_path, 0));
    }
    
    void file_system_navigator::create_layout()
    {
      auto* layout_line = new QHBoxLayout;
      layout_line->addWidget(label);
      layout_line->addWidget(_directory_line);
      layout_line->addWidget(_open_button);
    
      auto* layout = new QVBoxLayout;
      layout->addLayout(layout_line);
      layout->addWidget(_view);
      setLayout(layout);
    
      QSizePolicy lsp(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
      QSizePolicy vsp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
      _directory_line->setSizePolicy(lsp);
      _view->setMinimumWidth(800);
      _view->setMinimumHeight(600);
      _view->setSizePolicy(vsp);
    }
    
    void file_system_navigator::create_connections()
    {
      connect(_view, &QTreeView::doubleClicked, this,
              &file_system_navigator::update_from_tree);
    
      connect(_open_button, &QPushButton::clicked, this,
              &file_system_navigator::update_from_button);
    }
    
    void file_system_navigator::create_actions()
    {
      _multiple_files_action = new QAction{"add files to list ", new QAction(this)};
      connect(_multiple_files_action, &QAction::triggered, this,
              &file_system_navigator::multiple_files_action);
      addAction(_multiple_files_action);
    }
    
    int file_system_navigator::multiple_files_action()
    {
      auto        indexes = _view->selectionModel()->selectedIndexes();
      QStringList sl;
      for (const auto& index : indexes) sl.push_back(_model->filePath(index));
      sl.removeDuplicates();
      sl.sort(Qt::CaseSensitivity::CaseSensitive);
      emit new_files(sl);
      return 0;
    }
    
    
    int file_system_navigator::update_from_tree(const QModelIndex& index)
    {
      auto      fp = _model->filePath(index);
      QFileInfo fi{fp};
      if (fi.isDir())
      {
        _model->setRootPath(fp);
        _view->setRootIndex(_model->index(fp));
        _view->repaint();
        _directory_line->setText(fi.absoluteFilePath());
        set_last_path(fp);
        _view->resizeColumnToContents(0);
      }
      else if (fi.isFile()) { emit new_file(fp); }
      return 0;
    }
    
    int file_system_navigator::update_from_button()
    {
      auto lp       = get_last_path();
      auto new_path = QFileDialog::getExistingDirectory(
        this, tr("Open Directory"), lp,
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
      _view->setRootIndex(_model->index(new_path, 0));
      _view->resizeColumnToContents(0);
      _directory_line->setText(new_path);
      return 0;
    }
    
    void file_system_navigator::contextMenuEvent(QContextMenuEvent* event)
    {
      _menu->exec(event->globalPos());
    }
    
    void file_system_navigator::create_menus()
    {
      _menu->addAction(_multiple_files_action);
    }
    
    
    J 1 Reply Last reply 21 Mar 2024, 13:23
    0
    • O olivier_subatech
      21 Mar 2024, 13:16

      Hi there,
      I've bee struggling with these for a while and I just can't manage to make this work... I'd like the first column of my QTreeView to automatically resize to fit the content of the folder it displays and, it does not work.
      Can you please help me on this one.
      thank you very much for your help.

      Olivier

      #include "file_system_navigator.hxx"
      #include <QDebug>
      #include <string>
      
      file_system_navigator::file_system_navigator(QWidget* parent) :
        QWidget{parent},                                //
        path{""},                                       //
        label{new QLabel(tr("&current folder"), this)}, //
        _directory_line{new QLineEdit(this)},           //
        _open_button{new QPushButton("open...", this)}, //
        _model{new QFileSystemModel(this)},             //
        _view{new QTreeView(this)},                     //
        _menu{new QMenu(this)}
      {
        create_layout();
        init_widgets();
        create_connections();
        create_actions();
        create_menus();
      }
      
      file_system_navigator::~file_system_navigator() {}
      
      QString file_system_navigator::get_last_path()
      {
        QSettings settings("org", "soft");
        return settings.value("last_config_path").toString();
      }
      
      QString file_system_navigator::set_last_path(QString new_path)
      {
        QSettings settings("org", "soft");
        settings.setValue("last_config_path", new_path);
        return settings.value("last_config_path").toString();
      }
      
      
      void file_system_navigator::init_widgets()
      {
        label->setBuddy(_open_button);
      
        QString last_path = get_last_path();
        _directory_line->setText(last_path);
      
        // _model
        _model->setNameFilterDisables(true);
        _model->setFilter(QDir::AllEntries | QDir::AllDirs | QDir::NoSymLinks);
        // tree
        _view->setModel(_model);
        _view->setSortingEnabled(true);
        _view->sortByColumn(0, Qt::SortOrder::AscendingOrder);
        _view->setAlternatingRowColors(true);
        _view->setExpandsOnDoubleClick(false);
        _view->setItemsExpandable(false);
        _view->setSelectionMode(QTreeView::ContiguousSelection);
        // _view->hideColumn(2); // type
        _view->repaint();
      
        _model->setRootPath(last_path);
        _view->setRootIndex(_model->index(last_path, 0));
      }
      
      void file_system_navigator::create_layout()
      {
        auto* layout_line = new QHBoxLayout;
        layout_line->addWidget(label);
        layout_line->addWidget(_directory_line);
        layout_line->addWidget(_open_button);
      
        auto* layout = new QVBoxLayout;
        layout->addLayout(layout_line);
        layout->addWidget(_view);
        setLayout(layout);
      
        QSizePolicy lsp(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
        QSizePolicy vsp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
        _directory_line->setSizePolicy(lsp);
        _view->setMinimumWidth(800);
        _view->setMinimumHeight(600);
        _view->setSizePolicy(vsp);
      }
      
      void file_system_navigator::create_connections()
      {
        connect(_view, &QTreeView::doubleClicked, this,
                &file_system_navigator::update_from_tree);
      
        connect(_open_button, &QPushButton::clicked, this,
                &file_system_navigator::update_from_button);
      }
      
      void file_system_navigator::create_actions()
      {
        _multiple_files_action = new QAction{"add files to list ", new QAction(this)};
        connect(_multiple_files_action, &QAction::triggered, this,
                &file_system_navigator::multiple_files_action);
        addAction(_multiple_files_action);
      }
      
      int file_system_navigator::multiple_files_action()
      {
        auto        indexes = _view->selectionModel()->selectedIndexes();
        QStringList sl;
        for (const auto& index : indexes) sl.push_back(_model->filePath(index));
        sl.removeDuplicates();
        sl.sort(Qt::CaseSensitivity::CaseSensitive);
        emit new_files(sl);
        return 0;
      }
      
      
      int file_system_navigator::update_from_tree(const QModelIndex& index)
      {
        auto      fp = _model->filePath(index);
        QFileInfo fi{fp};
        if (fi.isDir())
        {
          _model->setRootPath(fp);
          _view->setRootIndex(_model->index(fp));
          _view->repaint();
          _directory_line->setText(fi.absoluteFilePath());
          set_last_path(fp);
          _view->resizeColumnToContents(0);
        }
        else if (fi.isFile()) { emit new_file(fp); }
        return 0;
      }
      
      int file_system_navigator::update_from_button()
      {
        auto lp       = get_last_path();
        auto new_path = QFileDialog::getExistingDirectory(
          this, tr("Open Directory"), lp,
          QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
        _view->setRootIndex(_model->index(new_path, 0));
        _view->resizeColumnToContents(0);
        _directory_line->setText(new_path);
        return 0;
      }
      
      void file_system_navigator::contextMenuEvent(QContextMenuEvent* event)
      {
        _menu->exec(event->globalPos());
      }
      
      void file_system_navigator::create_menus()
      {
        _menu->addAction(_multiple_files_action);
      }
      
      
      J Offline
      J Offline
      JonB
      wrote on 21 Mar 2024, 13:23 last edited by
      #2

      @olivier_subatech
      That is quite a lot of code! IIRC you are supposed to call resizeColumnToContents() either during a resize() event or (at least for testing/workaround) on a QTimerSingleshot(0) timeout set off when content changes so that it will happen after the new column content has been shown. You might try these to see if that alters the situation.

      1 Reply Last reply
      0
      • O Offline
        O Offline
        olivier_subatech
        wrote on 21 Mar 2024, 14:09 last edited by
        #3

        Hi and thank you for your answer @JonB
        I also tried to connect a signal emitted by my widget to the resizeColumnToContents since it's a slot. But, it did not work either

        J 1 Reply Last reply 21 Mar 2024, 14:30
        0
        • O olivier_subatech
          21 Mar 2024, 14:09

          Hi and thank you for your answer @JonB
          I also tried to connect a signal emitted by my widget to the resizeColumnToContents since it's a slot. But, it did not work either

          J Offline
          J Offline
          JonB
          wrote on 21 Mar 2024, 14:30 last edited by
          #4

          @olivier_subatech
          Either you'll be lucky and someone will analyze your code, or you could reduce it drastically to a minimal example.

          I know it would be a bit of work, but how about dropping this having any connection to QFileSystemModel? Try with a small model (e.g. Simple Tree Model Example), tinker to adjust data at runtime, and see if you can get that to work?

          Hmm, only just noticed you are QTreeView not QTableView. Maybe this works differently, I don't know. Google for qtreeview resizecolumntocontents, some people saying problems? https://groups.google.com/g/python_inside_maya/c/9MkkaXXmQX0/m/bEUTa5KnBAAJ claims

          self.header().setSectionResizeMode(QtWidgets.QHeaderView.Fixed) # This is setResizeMode in PySide1
          for i, c in enumerate(self.model().columns):
              self.header().resizeSection(i, c.pixelWidth)
          

          worked. Dunno.

          O 1 Reply Last reply 21 Mar 2024, 15:33
          0
          • J JonB
            21 Mar 2024, 14:30

            @olivier_subatech
            Either you'll be lucky and someone will analyze your code, or you could reduce it drastically to a minimal example.

            I know it would be a bit of work, but how about dropping this having any connection to QFileSystemModel? Try with a small model (e.g. Simple Tree Model Example), tinker to adjust data at runtime, and see if you can get that to work?

            Hmm, only just noticed you are QTreeView not QTableView. Maybe this works differently, I don't know. Google for qtreeview resizecolumntocontents, some people saying problems? https://groups.google.com/g/python_inside_maya/c/9MkkaXXmQX0/m/bEUTa5KnBAAJ claims

            self.header().setSectionResizeMode(QtWidgets.QHeaderView.Fixed) # This is setResizeMode in PySide1
            for i, c in enumerate(self.model().columns):
                self.header().resizeSection(i, c.pixelWidth)
            

            worked. Dunno.

            O Offline
            O Offline
            olivier_subatech
            wrote on 21 Mar 2024, 15:33 last edited by
            #5

            @JonB here a shorter version of my code

            #include "file_system_navigator.hxx"
            #include <QDebug>
            #include <string>
            
            file_system_navigator::file_system_navigator(QWidget* parent) :
              QWidget{parent},                    //
              _model{new QFileSystemModel(this)}, //
              _view{new QTreeView(this)}
            {
              create_layout();
              init_widgets();
              create_connections();
            }
            
            file_system_navigator::~file_system_navigator() {}
            
            void file_system_navigator::init_widgets()
            {
            
              // _model
              _model->setFilter(QDir::AllEntries | QDir::AllDirs | QDir::NoSymLinks);
              // tree
              _view->setModel(_model);
              _view->setSortingEnabled(true);
              _view->sortByColumn(0, Qt::SortOrder::AscendingOrder);
              _view->setSelectionMode(QTreeView::ContiguousSelection);
            
              _model->setRootPath(".");
              _view->setRootIndex(_model->index(".", 0));
              _view->setMinimumWidth(600);
              _view->setMinimumHeight(800);
            }
            
            /**
             * @brief config_selector::create_layout
             * @details constructor helper to layout the widget
             * @author Olivier Lemaire
             */
            void file_system_navigator::create_layout()
            {
              auto* layout = new QVBoxLayout;
              layout->addWidget(_view);
              setLayout(layout);
            }
            
            void file_system_navigator::create_connections()
            {
              connect(_view, &QTreeView::doubleClicked, this,
                      &file_system_navigator::update);
            }
            
            int file_system_navigator::update(const QModelIndex& index)
            {
              auto      fp = _model->filePath(index);
              QFileInfo fi{fp};
              if (fi.isDir())
              {
                _model->setRootPath(fp);
                _view->setRootIndex(_model->index(fp));
                _view->repaint();
              }
              return 0;
            }
            
            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 21 Mar 2024, 19:56 last edited by
              #6

              Hi,

              QFileSystemModel is asynchronous so you might be trying to update the column width while it's still loading.

              That said, you should be able to do what you want using the QHeaderView::setSectionResizeMode.

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

              O 1 Reply Last reply 22 Mar 2024, 09:04
              1
              • S SGaist
                21 Mar 2024, 19:56

                Hi,

                QFileSystemModel is asynchronous so you might be trying to update the column width while it's still loading.

                That said, you should be able to do what you want using the QHeaderView::setSectionResizeMode.

                O Offline
                O Offline
                olivier_subatech
                wrote on 22 Mar 2024, 09:04 last edited by olivier_subatech
                #7

                @SGaist Thank you very much for your answer...
                I tried _view->header()->setSectionResizeMode(QHeaderView::ResizeToContents); in my init_wodgets function, and it looks like it's working :)

                I also tried connect(_model, &QFileSystemModel::directoryLoaded, _view, [this]() { _view->resizeColumnToContents(0); }); which obviously works too and might be the right way to do it...

                Your answer was very useful. Thank you very much for your help :)

                1 Reply Last reply
                0
                • O olivier_subatech has marked this topic as solved on 22 Mar 2024, 09:26

                7/7

                22 Mar 2024, 09:04

                • Login

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