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. QTreeView shows all the subfolders, but not the parent folder.

QTreeView shows all the subfolders, but not the parent folder.

Scheduled Pinned Locked Moved Solved General and Desktop
qt 5.6treeviewqfilesystemmodedirectoryroot
7 Posts 4 Posters 5.2k 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.
  • P Offline
    P Offline
    Punit
    wrote on 25 May 2016, 06:56 last edited by Punit
    #1

    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.

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giupigna
      wrote on 1 Jun 2016, 07:39 last edited by
      #2

      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.

      1 Reply Last reply
      1
      • P Offline
        P Offline
        Punit
        wrote on 1 Jun 2016, 09:26 last edited by Punit 6 Jan 2016, 09:32
        #3

        @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

        R 1 Reply Last reply 1 Jun 2016, 13:40
        0
        • P Punit
          1 Jun 2016, 09:26

          @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

          R Offline
          R Offline
          raven-worx
          Moderators
          wrote on 1 Jun 2016, 13:40 last edited by raven-worx 6 Mar 2016, 08:37
          #4

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

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          4
          • G Offline
            G Offline
            giupigna
            wrote on 2 Jun 2016, 13:45 last edited by giupigna 6 Feb 2016, 13:46
            #5

            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.

            1 Reply Last reply
            1
            • P Offline
              P Offline
              Punit
              wrote on 3 Jun 2016, 08:34 last edited by
              #6

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

              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on 2 Apr 2020, 22:23 last edited by fcarney 4 Feb 2020, 22:23
                #7

                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.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                1

                • Login

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