簡體   English   中英

filterAcceptsRow() 到底是做什么的?

[英]What does filterAcceptsRow() exactly do?

一個目錄下有3個文件夾:

f:/root_folder/folder1
f:/root_folder/_folder2
f:/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_folder
HDD (F:)
HDD (E:)
HDD (D:)
C:
HDD (F:)
HDD (E:)
HDD (D:)
C:

並且 listView 是空的。

'source_parent' 是否無效? 然后我試試這個:

class myProxyModel(QSortFilterProxyModel):
    def filterAcceptsRow(self, source_row, source_parent):
        if not source_parent.isValid():
            print("index invalid")
            return False
        else: return True

在控制台上得到這個:

index invalid
index invalid

和 listView 中的 3 個文件夾:

在此處輸入圖片說明

現在我完全糊塗了。

filterAcceptsRow() 到底是做什么的?

您只需要過濾與 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_())

如果你不超載它什么都沒有。

如果您使用的類中提供的過濾器(通常為QSortFilterProxyModel )不能滿足您的需要,您只需重載它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM