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.



  • I had the same problem and I resolved it using a QSortFilterProxyModel on the FileSystemModel, filtering just the folder that will be the root of the treeView.
    Anyway I used the same proxy model to do something else.



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


  • Moderators

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



  • Thanks a lot. :) @raven-worx @giupigna. Problem solved.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.