隐藏空父文件夹QTreeView/QFileSystemModel

问题描述 投票:0回答:2

所以我有一个树视图,如下所示;

    #QTreeView widget
    #Shows files in set directory
    self.treeView = QtWidgets.QTreeView(self.centralWidget)
    self.treeView.setSortingEnabled(True)
    self.treeView.setObjectName("treeView")
    self.horizontalLayout_4.addWidget(self.treeView)
    self.file_model=QtWidgets.QFileSystemModel()
    self.file_model.setRootPath('C:\My Stuff\Movies')
    self.treeView.setModel(self.file_model)
    self.treeView.setRootIndex(self.file_model.index('C:\My Stuff\Movies'))
    self.treeView.setColumnWidth(0,275)
    self.file_model.setNameFilters(self.filterList)
    self.file_model.setNameFilterDisables(0)

如您所见,我有一个过滤器,它隐藏未通过过滤器的项目(例如 *.mkv),但是我的目录中有一些文件夹包含不符合过滤器要求的文件。该文件夹保留在我的树视图中,即使它是空的,我如何删除这些空文件夹(请记住,当我应用允许显示文件夹中的文件的过滤器时,我需要能够显示这些文件夹。

我正在运行 PyQt5、Python 3.5、Windows 7。

python pyqt treeview qfilesystemmodel
2个回答
1
投票

我们有同样的问题,这就是我尝试解决问题的方法。

您需要子类化

QSortFilterProxyModel
并覆盖
hasChildren
filterAcceptsRow

请注意,您需要调用子类

QFileSystemModel
setNameFilters
方法,而不是调用
QSortFilterProxyModel
nameFilters
方法。

这是我根据上面的实现最终得到的代码:

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class DirProxy(QSortFilterProxyModel):
    nameFilters = ''
    def __init__(self):
        super().__init__()
        self.dirModel = QFileSystemModel()
        self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs | QDir.Files) # <- added QDir.Files to view all files
        self.setSourceModel(self.dirModel)

    def setNameFilters(self, filters):
        if not isinstance(filters, (tuple, list)):
            filters = [filters]
        self.nameFilters = filters
        self.invalidateFilter()

    def hasChildren(self, parent):
        sourceParent = self.mapToSource(parent)
        if not self.dirModel.hasChildren(sourceParent):
            return False
        qdir = QDir(self.dirModel.filePath(sourceParent))
        return bool(qdir.entryInfoList(qdir.NoDotAndDotDot|qdir.AllEntries|qdir.AllDirs))
    
    def filterAcceptsRow(self, row, parent):
        source = self.dirModel.index(row, 0, parent)
        if source.isValid():
            if self.dirModel.isDir(source):
                qdir = QDir(self.dirModel.filePath(source))
                if self.nameFilters:
                    qdir.setNameFilters(self.nameFilters)
                return bool(qdir.entryInfoList(qdir.NoDotAndDotDot|qdir.AllEntries|qdir.AllDirs))

            elif self.nameFilters:  # <- index refers to a file
                qdir = QDir(self.dirModel.filePath(source))
                return qdir.match(self.nameFilters, self.dirModel.fileName(source)) # <- returns true if the file matches the nameFilters
        return True

class Test(QWidget):
    def __init__(self):
        super().__init__()
        
        self.dirProxy = DirProxy()
        self.dirProxy.dirModel.directoryLoaded.connect(lambda : self.treeView.expandAll())
        self.dirProxy.setNameFilters(['*.ai'])  # <- filtering all files and folders with "*.ai"
        self.dirProxy.dirModel.setRootPath(r"<Dir>")

        self.treeView = QTreeView()
        self.treeView.setModel(self.dirProxy)

        root_index = self.dirProxy.dirModel.index(r"<Dir>")
        proxy_index = self.dirProxy.mapFromSource(root_index)
        self.treeView.setRootIndex(proxy_index)

        self.treeView.show()

app = QApplication(sys.argv)
ex = Test()
sys.exit(app.exec_())

这是我所做的测试,结果对我来说看起来很好:

试验1: enter image description here

试验2: enter image description here

请阅读此问题以获取更多信息。


0
投票

如果

呢?

情况 1:您有一个目录,比如说 dir1,其中仅包含一个目录 dir2,其中包含一个 .ai 文件?

情况 2:dir3 仅包含 dir4,而 dir4 不包含任何内容?

我尝试用 C++ 编写你的解决方案,但这些情况看起来有问题,也许我错过了一些东西?

© www.soinside.com 2019 - 2024. All rights reserved.