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.
Forum Updated to NodeBB v4.3 + New Features

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.3k Views 2 Watching
  • 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