【问题标题】:QTreeView, QFileSystemModel, setRootPath and QSortFilterProxyModel with RegExp for filteringQTreeView、QFileSystemModel、setRootPath 和 QSortFilterProxyModel 与 RegExp 进行过滤
【发布时间】:2011-12-10 23:30:01
【问题描述】:

我需要显示特定目录的 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 上,这意味着所有驱动器等)

我做错了什么? :/

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

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

    我认为正在发生的事情是 一旦你开始过滤, 您作为根目录使用的索引没有 不再存在。然后视图重置为 作为根索引的无效索引。 过滤在整体上起作用 模型树,不只是你的一部分 看看你是否开始输入你的过滤器!

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

    因此,在继承 QSortFilterProxyModel 并在函数 filterAcceptsRow() 中检查一些 parent() 之后,这确实可以按预期工作了!

    【讨论】:

    • 您有机会分享您所做的修改吗?我现在遇到了这个确切的问题,但不知道如何解决它。
    • 很遗憾我无法再访问这个项目了。这是邮件列表线程:mentby.com/Group/qt-interest/…
    【解决方案2】:

    我通过 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() 循环更改为递归。

    【讨论】:

      猜你喜欢
      • 2018-04-02
      • 2012-09-03
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      • 2015-11-17
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多