筛选/搜索QListFiew中的QFileSystemModel(可能是QSortFilterProxyModel) - python

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

(我正在制作一个批量文件“重命名器”,只是我决定继续学习的项目)

我希望能够通过在“ getOut”行编辑中键入内容来搜索/过滤列表视图。这样的事情是我的目标(来自旧的随机youtube视频,但它使用的是QListWidget

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

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

所以我的问题归结为:

甚至有可能像我在gif中那样过滤QListView?
QFileSystemModel能够像这样被过滤/搜索吗?
如果上述2都可以,QSortFilterProxyModel是否是该工作的正确工具?
我应该使用其他模型还是要建立一个更基本且可以接受过滤的模型(我认为可以)?

我可以只使用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过滤器放入列表中。我可以用它过滤我想要的东西,但是我必须输入“ q”之类的内容来过滤其中带有“ Q”的内容。而“ self.homes”只是用户选择的我的路径/目录。

python参考方案

如果使用QSortFilterProxyModel正确实现了QFileSystemModel过滤,则将回答所有问题。

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

另一方面,您指出要使用QSortFilterProxyModel时遇到问题,在指出问题之前,您必须了解视图不知道,并且无论您是否知道模型是代理,都不会引起您的兴趣等待一个模型和一个QModelIndex作为属于该模型的rootIndex。在您的情况下,必须使用mapFromSource()方法将QFileSystemModel的索引转换为QSortFilterProxyModel的索引。

最后似乎有一个错误,因为当数据被过滤并且为空时,内部会更改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_())

Python sqlite3数据库已锁定 - python

我在Windows上使用Python 3和sqlite3。我正在开发一个使用数据库存储联系人的小型应用程序。我注意到,如果应用程序被强制关闭(通过错误或通过任务管理器结束),则会收到sqlite3错误(sqlite3.OperationalError:数据库已锁定)。我想这是因为在应用程序关闭之前,我没有正确关闭数据库连接。我已经试过了: connectio…

如何在PyQt4的动态复选框列表中检查stateChanged - python

所以我要从PyQt4的列表中添加复选框。但是我找不到在Window类中对每个状态使用stateChanged的方法。这是从列表元素添加它们的功能: def addCheckbox(self): colunas = Graphic(self.caminho).getColunas() for col in colunas: c = QtGui.QCheckBo…

Python pytz时区函数返回的时区为9分钟 - python

由于某些原因,我无法从以下代码中找出原因:>>> from pytz import timezone >>> timezone('America/Chicago') 我得到:<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD…

用大写字母拆分字符串,但忽略AAA Python Regex - python

我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…

如何打印浮点数的全精度[Python] - python

我编写了以下函数,其中传递了x,y的值:def check(x, y): print(type(x)) print(type(y)) print(x) print(y) if x == y: print "Yes" 现在当我打电话check(1.00000000000000001, 1.0000000000000002)它正在打印:<…