在QListFiew中过滤/搜索QFileSystemModel(可能是qsortfilterproxy model)

2024-09-27 21:32:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我要做的是过滤/搜索一个使用QFileSystemModel填充它的QListView:这是我现在使用的一个test/dummy文件夹创建的一些窗口

(我正在制作一个大容量文件“重命名器”,这正是我决定学习的项目)

我想通过在“getOut”行编辑中输入一些内容来搜索/过滤列表视图。像这样的东西是我的目标(这是从一个旧的随机youtube视频但是它使用的是QListWidget

我读到QSortFilterProxyModel可能是我想要使用的,但是当我使用代理设置列表视图“setRootIndex”时,它会抛出一个错误。在

TypeError: index(self, int, int, parent: QModelIndex = QModelIndex()): argument 1 has unexpected type 'str'

所以我的问题归结为:

  1. 有没有可能像我在gif中要的那样过滤QListView?在
  2. QFileSystemModel是否可以这样过滤/搜索?在
  3. 如果上面的2个都可以的话,QSortFilterProxyModel是否是该作业的正确工具?在
  4. 我应该使用一个不同的模型还是做一个更基本、更开放的过滤模型(我想你可以)?在

我可以通过使用QFileSystemModel的“setNameFilters”和“setNameFilterDisables(False)”来完成我正在尝试的工作,但是我必须以一种奇怪的方式来做,你可以在下面看到。在

def listPopulate(self):
    print('\ninside the listPopulate method now')
    getOut = self.getOutInputBox.text()
    gList = []
    gList.insert(0, getOut)
    if self.homes:
        if os.path.exists(self.homes):
            listModel = QtWidgets.QFileSystemModel()
            listModel.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries | QDir.Dirs | QDir.Files)
            listModel.setRootPath(self.homes)

            # proxyModel = QtCore.QSortFilterProxyModel()
            # proxyModel.setSourceModel(listModel)

            self.mainListView.setModel(listModel)
            self.mainListView.setRootIndex(listModel.index(self.homes))
            if not getOut:
                print('\ngetOut empty')
            else:
                print(getOut)
                listModel.setNameFilters(gList)
                listModel.setNameFilterDisables(False)

所有“gList”的东西都是因为“setNameFilters”只接受一个列表(我想这通常用于过滤文件扩展名),所以我使用getOut过滤器并将其放入一个列表中。我想用它来过滤。和'自我家园我的用户选择了路径。在


Tags: 文件self视图列表ifprintqlistviewhomes
1条回答
网友
1楼 · 发布于 2024-09-27 21:32:53

如果使用QSortFilterProxyModel正确实现了QFileSystemModel筛选,则所有问题都会得到解答。在

以下解决方案仅适用于Qt>;=5.10,因为在该版本中,我们添加了recursiveFilteringEnabled属性,该属性允许在树模型中进行递归过滤,如本例所示。在

另一方面,您指出您在使用QSortFilterProxyModel时遇到了问题,在指出问题所在之前,您必须了解视图不知道也不感兴趣如果您知道模型是否是代理,只需等待模型和QModelIndex作为属于该模型的根索引。在您的例子中,必须使用mapFromSource()方法将QFileSystemModel的索引转换为QSortFilterProxyModel的索引。在

最后,似乎有一个bug,因为当数据被过滤后变为空时,rootIndex在内部发生了变化,因此必须像我在回答中所做的那样重新建立它。在

from PyQt5 import QtCore, QtGui, QtWidgets

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        le = QtWidgets.QLineEdit(textChanged=self.on_textChanged)
        self.lv = QtWidgets.QListView()

        self._dirpath = QtCore.QDir.homePath()

        self.file_model = QtWidgets.QFileSystemModel()
        self.file_model.setRootPath(QtCore.QDir.rootPath())
        self.file_model.setFilter(QtCore.QDir.NoDotAndDotDot 
            | QtCore.QDir.AllEntries 
            | QtCore.QDir.Dirs 
            | QtCore.QDir.Files)
        self.proxy_model = QtCore.QSortFilterProxyModel(
            recursiveFilteringEnabled=True,
            filterRole=QtWidgets.QFileSystemModel.FileNameRole)
        self.proxy_model.setSourceModel(self.file_model)
        self.lv.setModel(self.proxy_model)
        self.adjust_root_index()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(le)
        lay.addWidget(self.lv)

    @QtCore.pyqtSlot(str)
    def on_textChanged(self, text):
        self.proxy_model.setFilterWildcard("*{}*".format(text))
        self.adjust_root_index()

    def adjust_root_index(self):
        root_index = self.file_model.index(self._dirpath)
        proxy_index = self.proxy_model.mapFromSource(root_index)
        self.lv.setRootIndex(proxy_index)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

相关问题 更多 >

    热门问题