QTreeView shows all the subfolders, but not the parent folder.
-
I'm trying to get QTreeView (using an underlying QFileSystemModel) to show a directory tree. If I set the RootPath to the parent directory, then I see all the children, but not the parent.
I want to see parent folder and all it's subfolders.
Code:
QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); viewtree=new QTreeView; dir1=new QFileSystemModel(this); dir1->setRootPath(dir); dir1->setFilter(QDir::NoDotAndDotDot |QDir::AllDirs); viewtree->setModel(dir1); viewtree->setRootIndex(dir1->index(dir));
I want to show Parent folder along with it's subfolders in QTreeView.
Any Suggestions?
Thanks. -
@giupigna @Lifetime-Qt-Champion @Moderators @Qt-Champions-2015
I have a folder structure like this.
User |-Mac |-Desktop |-test2 |-First |-Second
I am trying to show a folder "test2" and all it's subfolders. I am a newbiew so don't know much about QSortFilterProxyModel. First of all if I select "test2" when prompt to select folder, my treeview only shows subfolders i.e. "First" and "Second". So I am using QDir::cdUp() function to set Desktop as my root folder. Now my treeview show all folders present inside "Desktop" including "test2". But, I want to show "test2" and all it's subfolders only.
I have created my own proxy model to do so, but it's not working. Please help!
CODE:
"MyProxy.h"
class MyProxy : public QSortFilterProxyModel { Q_OBJECT public: MyProxy(); protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; };
"MyProxy.cpp"
#include "myproxy.h" MyProxy::MyProxy() { } bool MyProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { QModelIndex node= sourceModel()->index(source_row, 0, source_parent); QString foldername= sourceModel()->data(node, Qt::DisplayRole).toString(); if(QString::compare(foldername ,"test2")==0) return true; else return false; }
"mainwindow.cpp"
#include "myproxy.h" ................ button=new QPushButton; button->setText("Click"); connect(button,SIGNAL(clicked(bool)),this,SLOT(work())); dir=new QFileSystemModel; messagesTableWidget=new QTreeView; model=new MyProxy; void MainWindow::work() { QString folderpath = QFileDialog::getExistingDirectory(this, tr("Open Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QDir* direct = new QDir(folderpath); direct->setPath(folderpath); direct->cdUp(); dir->setRootPath(direc->path()); dir->setFilter(QDir::NoDotAndDotDot |QDir::AllDirs); model->setSourceModel(dir); messagesTableWidget->setModel(model); messagesTableWidget->setRootIndex(model->mapFromSource(dir->index(direc->path()))); }
Thanks
-
@Punit
try something like this:bool MyProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { QFileSystemModel* model = qobject_cast<QFileSystemModel*>( sourceModel ); QModelIndex index = model->index(source_row, 0, source_parent); QModelIndex rootIndex = model->index( rootPath ); // create some getter/setter methods for the "rootPath" (QString) Q_ASSERT( rootIndex.isValid() ); if( !rootIndex.isValid() ) return false; return (index.isValid() && index == rootIndex) || this->isChildIndexOf(index, rootIndex); } bool MyProxy::isChildIndexOf( const QModelIndex & child, const QModelIndex & parent ) { if( !child.isValid() ) return false; QModelIndex idx = parent; do { if( child.parent() == idx ) return true; idx = idx.parent(); if( child.parent() == idx ) // in case parent is already invalid we need to check here again return true; } while( idx.isValid() ); return false; }
written straight from my head and thus untested.
-
I did it in the following way:
bool PatternTreeFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { QFileSystemModel *model = qobject_cast<QFileSystemModel*>(sourceModel()); QDir pathDir(m_path); // path of the root folder QModelIndex idx = source_parent.child(source_row, 0); QDir sourceFilePath(model->filePath(idx) + QDir::separator() + "test2"); QString sourceAbsFilePath = sourceFilePath.absolutePath(); QString pathDirAbsFilePath = pathDir.absolutePath(); if (sourceAbsFilePath.startsWith(pathDirAbsFilePath)) if (model->isDir(idx)) return true; return false; }
In my case I show only the folders in the treeView. Looking at the raven 's code it's better and more faster than mine, but I don't know if it works.
Anyway my advise it: debug, debug, debug a lot how I did.
-
I had issues making these solutions work for the QML TreeView. I ended up setting the root path of my QFileSystemModel to the directory I wanted to view. Then I set the rootIndex in the TreeView to the parent of the index for that directory. This is of course showed its siblings. Then I did the following to filter those siblings away. I also made this optional through a property as there are times when I want that behavior:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { FileSystemModel* tmodel = qobject_cast<FileSystemModel*>(parent()); if(tmodel){ QModelIndex index = tmodel->index(source_row, 0, source_parent); QModelIndex rootIndex = tmodel->index(tmodel->rootPath()); if(!rootIndex.isValid() || !index.isValid()) return false; return ((index == rootIndex) || !(tmodel->filtersiblings() && isSiblingOf(index, rootIndex))); } return false; } bool isSiblingOf(const QModelIndex& index, const QModelIndex& parent) const { if(!index.isValid() || !parent.isValid()) return false; QModelIndex sibling; int row=0; do{ sibling = parent.sibling(row,0); if(sibling == index) return true; ++row; }while(sibling.isValid()); return false; }
I took more of a blacklist approach versus a whitelist approach.