【问题标题】:How to show only folders with specific files using QTreeView and QFileSystemModel?如何使用 QTreeView 和 QFileSystemModel 仅显示具有特定文件的文件夹?
【发布时间】:2012-03-24 06:36:51
【问题描述】:

我在使用 QTreeView 和 QFileSystemModel 过滤特定文件夹时遇到问题。

我将我的根 QFileSystemModel 设置为特定文件夹 - 这有效。但我只想显示包含.jpg 文件的文件夹。这可能吗?

我过滤了.jpg 文件并且可以工作,但是我的QTreeView 显示了所有文件夹,甚至那些没有.jpg 文件的文件夹。因此,如果用户尝试打开某个没有.jpg 文件的文件夹,则什么也不会发生。

如何隐藏这些文件夹?

注意:下面有部分代码。

QStringList filterTypeFile;
filterTypeFile.append("*.jpg");
this->m_pModelTreeViewImage->setNameFilters(filterTypeFile);
this->m_pModelTreeViewImage->setNameFilterDisables(false);

this->ui->treeViewImages->setModel(this->m_pModelTreeViewImage);

【问题讨论】:

    标签: qt qtreeview qfilesystemmodel


    【解决方案1】:

    恐怕坏消息:如果你想要那种行为,你将不得不自己实现它。文件系统读取器只是不适合做这种事情。

    这也是有原因的。通常支持隐藏文件,因为它既快速又简单 - 文件名与您的正则表达式匹配或不匹配。隐藏目录(或使它们无法打开 - 相同的区别)要复杂得多。你不能只看目录名;你必须爬取文件系统,寻找可打开的文件。而且硬盘访问速度。想象一下,您的用户正在查看一个非常靠近文件系统根目录的目录 - 您必须浏览所有内容。然后,如果过滤器改变了,你就必须重新做一遍。

    还要考虑:已建立的模式是只隐藏文件,从不隐藏目录。这可能是上述技术困难的结果,但它已成为标准的 UI 行为。因此,如果用户遇到的文件系统查看器没有显示他们期望的所有文件夹(或者如果他们无法打开某些文件夹,看似是随机的),他们会假设某些东西是坏了。

    也就是说,如果无论如何都有充分的理由这样做,您可能会重新实现 QFileSystemModel 来做您想做的事情(或者,如果失败,您当然可以让 AbstractModel 子类的行为与您描述的一样)。您的用户会适应,尤其是在有充分理由采用新行为的情况下。

    祝你好运!

    【讨论】:

    • 谢谢@Xavier Holt!我了解您的回答的所有内容,并且真的很有意义。顺便说一句,我忘了在我的提问中再写一个注释...在 Qt 文档中,在 QFileSystemModel::setFilter() 会谈中:请注意,您设置的过滤器应始终包含 QDir::AllDirs 枚举值,否则 QFileSystemModel 将无法读取目录结构。。我将研究是否真的有必要实施这种行为。无论如何,非常感谢!
    • 好吧,我正在尝试实现我自己的 QTreeView。我有问题,因为我不知道如何在我的 QTreeView 中选择第一个 QModelIndex。注意:我使用的是 QFileSytemModel。
    • @AdrianoLeal - 这只是一个猜测,因为我只是切线使用了 Qt 的 MVC 东西,但我会尝试获取所有“结构”相关信息(包括“第一个”模型index) 通过 QFileSystemModel 而不是视图。看起来 Qt 视图实际上只是为了处理 UI 操作而设计的,而模型本身则负责组织。
    【解决方案2】:

    您应该从QSortFilterProxyModel 派生并重新实现 virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const 功能。像这样的

    bool JPGFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
    {
       QFileSystemModel *fs = static_cast<QFileSystemModel*>(sourceModel());
       QModelIndex i = fs->index(source_row, 0, source_parent);
       bool accept=false;
       if( fs->hasChildren(i) ){
         for( int j=0; j<fs->rowCount(i); j++  )
           if( fs->fileInfo(fs->index(j,0,i)).suffix()=="jpg" ){
             accept=true;
             break;
           }
       }
       return accept;
    }
    

    我自己没有尝试过。它很慢,但应该可以工作。

    【讨论】:

    • 这个解决方案看起来很优雅,但它不起作用,因为 QFileSystemModel 似乎只包含消耗的 QModelIndex。无法递归删除空目录,但可能只删除叶子目录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多