所以我有一个树视图,如下所示;
#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。
我们有同样的问题,这就是我尝试解决问题的方法。
您需要子类化
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:您有一个目录,比如说 dir1,其中仅包含一个目录 dir2,其中包含一个 .ai 文件?
情况 2:dir3 仅包含 dir4,而 dir4 不包含任何内容?
我尝试用 C++ 编写你的解决方案,但这些情况看起来有问题,也许我错过了一些东西?