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

can't manage to resize column of QTreeView Automatically

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 925 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.
  • O Offline
    O Offline
    olivier_subatech
    wrote on 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);
    }
    
    
    JonBJ 1 Reply Last reply
    0
    • O olivier_subatech

      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);
      }
      
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on 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 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

        JonBJ 1 Reply Last reply
        0
        • O olivier_subatech

          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

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 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
          0
          • JonBJ JonB

            @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 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
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on 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
              1
              • SGaistS SGaist

                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 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

                • Login

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