为了账号安全,请及时绑定邮箱和手机立即绑定

filterAcceptsRow() 究竟做了什么?

filterAcceptsRow() 究竟做了什么?

慕森卡 2022-05-19 14:01:02
一个目录中有3个文件夹:f:/root_folder/folder1f:/root_folder/_folder2f:/root_folder/folder3.asset我尝试自定义 QSortFilterProxyModel.filterAcceptsRow() 仅显示带有 .asset 后缀的文件夹。** 我知道我可以使用 QFileSystemModel.setNameFilters([*.asset]) 来做到这一点。但有时它不起作用。我有 Python3.7 + PySide2 5.13.0。# first inherit a QFileSystemModel instance:listModel = QFileSystemModel()# let the instance display only folders, except for '.' and '..':listModel.setFilter(QDir.NoDotAndDotDot | QDir.Dirs)# assgin a root path. i just want the model to search the 'f:/root_folder':listModel.setRootPath("f:/root_folder")# add a custom QSortFilterProxyModel:myProxy = myProxyModel()myProxy.setSourceModel(listModel)# finally show result in a QListView:# 'ui' is a QWidget object that contain a listView widget.ui.listView.setModel(myProxy)ui.listView.setRootIndex(myProxy.mapFromSource(listModel.index("f:/root_folder")))这是自定义的 QSortFilterProxyModel:# test:class myProxyModel(QSortFilterProxyModel):    def filterAcceptsRow(self, source_row, source_parent):        return True此时,脚本按预期工作:列表中有 3 个文件夹且没有过滤器。如果我理解正确,“source_parent”应该是“listModel”的 QModelIndex,它指向目录“f:/root_folder”。并且“source_row”应该是“f:/root_folder”(三个文件夹之一)中某个项目的“序号”。对?然后我添加了自己的过滤器:# first try:class myProxyModel(QSortFilterProxyModel):    def filterAcceptsRow(self, source_row, source_parent):        source_model = self.sourceModel()         # 'source_model' should be the 'listModel', right?        source_index = source_model.index(source_row, 0, source_parent)        # 'source_index' is a QModelIndex, pointing to 'folder1' or '_folder2' or 'folder3.asset'.        # start filtering        filename = source_index.data(Qt.DisplayRole)        print(filename) # check        if filename[-6:] == ".asset": return True        else: return False它应该在控制台上显示 3 个文件夹名称,在列表中显示 1 个文件夹(folder3.asset)。但我得到了非常奇怪的结果!这是控制台的结果:**它多次列出了我所有的硬盘HDD (F:)root_folderHDD (F:)HDD (E:)HDD (D:)C:HDD (F:)HDD (E:)HDD (D:)C:现在我完全糊涂了。filterAcceptsRow() 到底是做什么的?
查看完整描述

2 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

您只需过滤与 QFileSystemModel 的 rootPath() 关联的 inde 的子项:


from PySide2 import QtCore, QtGui, QtWidgets



class SuffixDirProxyModel(QtCore.QSortFilterProxyModel):

    def __init__(self, parent=None):

        super().__init__(parent)

        self._suffix = ""


    def filterAcceptsRow(self, source_row, source_parent):

        source_model = self.sourceModel()

        if (

            self._suffix

            and isinstance(source_model, QtWidgets.QFileSystemModel)

            and source_parent == source_model.index(source_model.rootPath())

        ):

            index = source_model.index(source_row, 0, source_parent)

            name = index.data(QtWidgets.QFileSystemModel.FileNameRole)

            file_info = source_model.fileInfo(index)

            return name.split(".")[-1] == self._suffix and file_info.isDir()

        return True


    @property

    def suffix(self):

        return self._suffix


    @suffix.setter

    def suffix(self, s):

        self._suffix = s

        self.invalidateFilter()



if __name__ == "__main__":

    import sys


    app = QtWidgets.QApplication(sys.argv)


    model = QtWidgets.QFileSystemModel()

    model.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Dirs)


    path = # "f:/root_folder"

    model.setRootPath(path)


    proxy = SuffixDirProxyModel()

    proxy.suffix = "asset"

    proxy.setSourceModel(model)


    w = QtWidgets.QListView()

    w.setViewMode(QtWidgets.QListView.IconMode)

    w.setModel(proxy)

    w.setRootIndex(proxy.mapFromSource(model.index(path)))

    w.show()

    sys.exit(app.exec_())


查看完整回答
反对 回复 2022-05-19
?
喵喔喔

TA贡献1735条经验 获得超5个赞

如果你不超载它什么都没有。

QSortFilterProxyModel如果您使用的类中提供的过滤器通常不能满足您的需求,您只需要重载它。


查看完整回答
反对 回复 2022-05-19
  • 2 回答
  • 0 关注
  • 283 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信