Question

I have a problem filtering specific folder using QTreeView and QFileSystemModel.

I set my root QFileSystemModel to a specific folder - this works. But I want to show just folders that contain .jpg files. Is this possible?

I filter .jpg files and that works, but my QTreeView shows all folders, even those that do not have .jpg files. So if the user tries to open some folder without .jpg files, nothing happens.

How can I hide those folders?

Note: below there are part of the code.

QStringList filterTypeFile;
filterTypeFile.append("*.jpg");
this->m_pModelTreeViewImage->setNameFilters(filterTypeFile);
this->m_pModelTreeViewImage->setNameFilterDisables(false);

this->ui->treeViewImages->setModel(this->m_pModelTreeViewImage);
Was it helpful?

Solution

Bad news, I'm afraid: You're going to have to implement this yourself if you want that sort of behaviour. File system readers just aren't set up to do this sort of thing.

There's a reason for that, too. Hiding files is commonly supported because it's fast and easy - either a filename matches your regex or it doesn't. Hiding directories (or making them unopenable - same difference) is a lot trickier. You can't just look at the directory name; you have to crawl the file system, looking for openable files. And hard drive access is slow. Imagine that your user is looking at a directory very close to the root of your file system - you'd have to crawl through everything. And then, if the filter changed, you'd have to do it all again.

Also consider: The established pattern for this is to only hide files, and never hide directories. This is probably as a result of the technical difficulties described above, but it has become a standard UI behaviour. So if a user comes across a file system viewer that isn't showing all the folders they expect (or if they can't open certain folders, seemingly at random), they're going to assume something's broken.

That said, if there's a good reason to do it anyway, you could probably reimplement QFileSystemModel to do what you want (or, failing that, you could certainly get an AbstractModel subclass to behave like you've described). Your users will acclimate, especially if there's a good reason for the new behaviour.

Good luck!

OTHER TIPS

You should derive from QSortFilterProxyModel and reimplement the virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const function. Something like this

bool JPGFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
   QFileSystemModel *fs = static_cast<QFileSystemModel*>(sourceModel());
   QModelIndex i = fs->index(source_row, 0, source_parent);
   bool accept=false;
   if( fs->hasChildren(i) ){
     for( int j=0; j<fs->rowCount(i); j++  )
       if( fs->fileInfo(fs->index(j,0,i)).suffix()=="jpg" ){
         accept=true;
         break;
       }
   }
   return accept;
}

I haven't tried this on my own. It is slow, but should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top