I'm trying to create a QFileDialog that will eventually select a file based on a filter, but I want to limit the user to only be able to select from certain directories from a common directory and I haven't had any luck.
I've tried Filtering directories displayed in a QFileDialog, qfiledialog - Filtering Folders? and How to set filter for directories in qfiledialog and haven't had any luck. I've tried creating a QSortFilterProxyModel but it isn't working as I'm expecting.
Here's what I currently have:
class FileFilterProxyModel : public QSortFilterProxModel
{
protected:
virtual bool filterAcceptsRow (int row, const QModelIndex &parent) const;
}
bool FileFilterProxyModel::filterAcceptsRow (int row, const QModelIndex &parent) const
{
QModelIndex index0 = sourceModel()->index (row, 0, parent);
QFileSystemModel *fileModel = qobject_cast<QFileSystemModel*> (sourceModel());
if ((fileModel != NULL) and (fileModel->isDir (index0))
{
if (fileModel->fileName(index0).startsWith ("di_"))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
Which is called by:
QFileDialog dialog;
FileFilterProxyModel *proxyModel = new FileFilterProxyModel;
dialog.setProxyModel (proxyModel);
dialog.setOption (QFileDialog::DontUseNativeDialog);
dialog.setDirectory (directoryName);
dialog.setFileMode (QFileDialog::ExistingFile);
dialog.exec ();
The result is really confusing me. When I run the QFileDialog with the FileFilterProxyModel it doesn't show directories (even though there are directories that match the filter). If I add a qDebug() statement before the check for the fileName it only shows the entries for the path to the specified directory.
What's really strange is that if I make the section where it checks if the directory name starts with "di_" to false and change the other case to true it shows everything but the directories that start with "di_", which I would expect.
I can't figure out how changing the result of the check on the start of the directory name would completely change the directories that are being checked.
Once I get the directories filtered and displayed, I'll then need to filter the subsequent filenames based on a different filter. Can I use the FileFilterProxyModel for that or do I need to do something different?
UPDATE
Thanks to @C137 I was able to get only the directories that I wanted displayed and I was able to get the files filtered by adding
dialog.SetNameFilter ("<enter filter here>");
I think I knew where the problem is, first I changed the
FileFilterProxyModelto become the default filter, like this:And setting dialog directory to
"E:/A/B". As directoryAis invalid, directoriesAandBwon't be displayed along with all their content.Now, when I set the filter to this implementation:
Then directory
Balong side all it's directories that start withdi_are shown. I think this because all directories in thepathto these directories are valid.Now this is happening because everything in the path to these files/directories is valid, except for directories starting with
di_that's why they aren't shown.Finally a complete clean implementation would be:
Which is called by:
And now I can sleep in piece :D