can't manage to resize column of QTreeView Automatically
-
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("¤t 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); }
-
@olivier_subatech
That is quite a lot of code! IIRC you are supposed to callresizeColumnToContents()
either during aresize()
event or (at least for testing/workaround) on aQTimerSingleshot(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. -
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 -
@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
notQTableView
. Maybe this works differently, I don't know. Google forqtreeview resizecolumntocontents
, some people saying problems? https://groups.google.com/g/python_inside_maya/c/9MkkaXXmQX0/m/bEUTa5KnBAAJ claimsself.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.
-
@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; }
-
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.
-
@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 :)
-