PySide2中QListView结合QSortFilterProxyModel搜索部分场景失效求助
QListView搜索无效时自动重置到根目录的问题解决
问题描述
将第三方代码适配为PySide2版本后,搜索功能出现异常:当输入不存在的首字母或数字时,QListView会自动重置到根目录'',而非保持在指定的初始目录。
问题代码
from PySide2 import QtCore, QtGui, QtWidgets class Widget(QtWidgets.QWidget): def __init__(self, parent=None): super(Widget, self).__init__(parent) le = QtWidgets.QLineEdit() le.textChanged.connect(self.on_textChanged) self.lv = QtWidgets.QListView() self._dirpath = "d:/" 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.Slot(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_())
问题原因
当输入的关键词无匹配结果时,代理模型会过滤掉所有内容,包括初始目录d:/对应的索引。此时mapFromSource返回无效索引,调用setRootIndex传入无效索引时,QListView会自动重置到模型的根目录(即空路径)。
解决方法
修改adjust_root_index方法,仅在代理索引有效时才更新QListView的根索引,无效时保持当前根索引不变:
def adjust_root_index(self): root_index = self.file_model.index(self._dirpath) proxy_index = self.proxy_model.mapFromSource(root_index) # 仅当代理索引有效时才更新根目录 if proxy_index.isValid(): self.lv.setRootIndex(proxy_index)
完整修改后代码
from PySide2 import QtCore, QtGui, QtWidgets class Widget(QtWidgets.QWidget): def __init__(self, parent=None): super(Widget, self).__init__(parent) le = QtWidgets.QLineEdit() le.textChanged.connect(self.on_textChanged) self.lv = QtWidgets.QListView() self._dirpath = "d:/" 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.Slot(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) if proxy_index.isValid(): self.lv.setRootIndex(proxy_index) if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) w = Widget() w.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者wayfarer
相关产品推荐
相关产品推荐

