QTreeView, QFileSystemModel, setRootPath and QSortFilterProxyModel with RegExp for filtering

I need to show a QTreeView of a specific directory, and I want to give the user the ability to filter files using RegExp.

As far as I understand the Qt documentation, I can achieve this with the classes mentioned in the title, like this:

// Create the Models QFileSystemModel *fileSystemModel = new QFileSystemModel(this); QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); // Set the Root Path QModelIndex rootModelIndex = fileSystemModel->setRootPath("E:\\example"); // Assign the Model to the Proxy and the Proxy to the View proxyModel->setSourceModel(fileSystemModel); ui->fileSystemView->setModel(proxyModel); // Fix the TreeView on the Root Path of the Model ui->fileSystemView->setRootIndex(proxyModel->mapFromSource(rootModelIndex)); // Set the RegExp when the user enters it connect(ui->nameFilterLineEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterRegExp(QString))); 

When the program starts, TreeView is correctly attached to the specified directory. But as soon as the user changes RegExp, it seems that TreeView has forgotten its RootIndex. After deleting all the text in RegExp LineEdit (or entering RegExp type ".") It displays all the directories again (on Windows, this means all drives, etc.)

What am I doing wrong?:/

+4
source share
2 answers

I got a response from the Qt mailing list that explained this problem:

What I think is happening is that as soon as you start filtering, the index that you use as your root does not last longer. Then, the view is reset to an invalid index as the root index. Filtering works as a whole model tree, not just see if you are starting to enter your filter!

I think you will need a modified proxy model to do what you want. It should only apply filtering items under your root path, but let the root path itself (and everything else).

So, after subclassing QSortFilterProxyModel and some parent () check in filterAcceptsRow () function, this works as expected now!

+9
source

I found this through Google and developed a solution based on this thread (and other Google results). You can find my solution at:

https://github.com/ghutchis/avogadro/blob/testing/libavogadro/src/extensions/sortfiltertreeproxymodel.h

https://github.com/ghutchis/avogadro/blob/testing/libavogadro/src/extensions/sortfiltertreeproxymodel.cpp

One thing you should remember (not mentioned here) is that child lines are not automatically selected by QFileSystemModel, so you need to call fetchMore (). In my case, we have only one level of subdirectories, so it is pretty simple.

If your code wanted to handle more diverse directory hierarchies, you would need to modify the for () loop at the bottom of the AcceptsRow () filter to be recursive.

+3
source

Source: https://habr.com/ru/post/1315192/


All Articles