我想做的是过滤/搜索使用QFileSystemModel填充它的QListView:这是我现在使用的一个test / dummy文件夹的某些窗口
(我正在制作一个批量文件“重命名器”,只是我决定随身学习的项目)
我希望能够通过在“ getOut”行编辑中键入内容来搜索/过滤列表视图。我的目标是这样(来自旧的随机youtube视频,但它使用的是QListWidget
我了解到QSortFilterProxyModel可能是我想要使用的,但是当我使用代理设置列表视图“ setRootIndex”时,它会引发错误。
TypeError: index(self, int, int, parent: QModelIndex = QModelIndex()): argument 1 has unexpected type 'str'
所以我的问题归结为:
我可以只使用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”只是用户选择的我的路径/目录。
答案 0 :(得分:0)
如果使用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_())