带有RegExp的QTreeView,QFileSystemModel,setRootPath和QSortFilterProxyModel用于过滤

时间:2010-07-09 12:08:25

标签: c++ qt

我需要显示特定目录的QTreeView,并且我想让用户使用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)));

启动程序时,TreeView正确地固定到指定的目录。但是一旦用户更改了RegExp,看起来TreeView就会忘记它的RootIndex。删除RegExp LineEdit中的所有文本(或输入类似“。”的RegExp)后,它再次显示所有目录(在Windows上,这意味着所有驱动器等等)

我做错了什么? :/

2 个答案:

答案 0 :(得分:9)

我收到了Qt邮件列表的回复,该列表解释了这个问题:

  

我认为正在发生的事情就是这样   一旦你开始过滤,   您使用的索引作为根没有   更长的存在。视图然后重置为   无效索引作为根索引。   过滤工作总体上起作用   模型树,而不仅仅是你的一部分   看看你是否开始输入过滤器了!

     

我认为你需要一个   修改代理模型来做你的事   想。它应该只适用于   过滤根目录下的项目   路径,但让根路径本身   (以及其他一切)。

因此,在对函数filterAcceptsRow()进行子类化QSortFilterProxyModel和一些parent()检查之后,现在可以正常工作了!

答案 1 :(得分: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()循环更改为递归。