【问题标题】:Hide empty parent folders QTreeView/QFileSystemModel隐藏空父文件夹 QTreeView/QFileSystemModel
【发布时间】:2022-05-12 06:21:51
【问题描述】:

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

    #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


    【解决方案1】:

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

    您需要继承QSortFilterProxyModel 并覆盖hasChildrenfilterAcceptsRow

    请注意,您需要调用子类QSortFilterProxyModelnameFilters 方法,而不是调用QFileSystemModelsetNameFilters

    这是我最终基于上述实现的代码:

    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_())
    

    这是我所做的测试,结果在我看来还不错:

    试验一:

    试验 2:

    请阅读this question了解更多信息。

    【讨论】:

      猜你喜欢
      • 2014-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      相关资源
      最近更新 更多