2010-07-09 256 views
4

我需要显示一个特定目录的QTreeView,并且我想让用户有可能用RegExp过滤这些文件。QTreeView,QFileSystemModel,setRootPath和QSortFilterProxyModel用RegExp进行过滤

据我所知Qt文档我可以在标题这样提到的类实现这一点:

// 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))); 

当开始该程序的树视图被正确地固定在指定的目录。但只要用户更改RegExp,它就像TreeView忘记RootIndex一样。删除RegExp LineEdit中的所有文本(或输入RegExp,如“。”)后,它再次显示所有目录(在Windows上,这意味着所有驱动器等)

我在做什么错? :/

回答

9

我从Qt的邮件列表,它解释了这个问题的回应:

我认为正在发生的事情,是因为 一旦你开始过滤时, 索引你为你的根使用没有 更长的存在。该视图然后重置为 作为根索引的无效索引。 这个过滤在整个 模型树上工作,而不仅仅是你在 看到你是否开始进入你的过滤器的部分!

我想你将需要一个 修改代理模型来做你想要的东西 。它应该只对 路径下的项目应用 筛选,但只允许根路径本身 (以及其他任何项目)。

因此,在功能filterAcceptsRow()中检查子类QSortFilterProxyModel和一些parent()检查后,现在按预期工作!

+0

你有没有可能分享你所做的修改?我现在遇到了这个确切的问题,但我不知道如何解决它。 – 2011-04-19 22:13:56

+0

很遗憾,我无法再访问此项目。这是邮件列表线程:http://www.mentby.com/Group/qt-interest/qtreeview-qfilesystemmodel-setrootpath-and-qsortfilterproxymodel-with-regexp-for-filtering.html – Strayer 2011-05-23 19:44:09

3

我通过Google发现了这个问题,并根据此线程(以及其他Google搜索结果)制定了解决方案。你可以找到我的解决办法:

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

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

有一件事你必须记住(这不是这里所说)是子行不能由QFileSystemModel自动获取,所以你必须调用fetchMore()在它们上面。就我而言,我们只有一层子目录,所以它相当容易。

如果您的代码想要处理更多不同的目录层次结构,则需要将filterAcceptsRow()底部附近的for()循环更改为递归。

相关问题