使用QFileSystemModel过滤并调用filePath函数时程序崩溃
问题解决:QListView结合QSortFilterProxyModel点击崩溃问题
问题根源
当QListView使用QSortFilterProxyModel作为数据模型时,clicked信号传递的是代理模型的索引对象,而QFileSystemModel.filePath()方法仅能接收自身(源模型)的索引。直接将代理索引传入源模型方法,会导致内存访问越界,触发SIGSEGV信号使程序崩溃。
解决方案
在调用filePath()前,通过代理模型的mapToSource()方法,将代理索引转换为源模型对应的索引,再传入源模型方法。
修正后的关键代码
修改get_file_path函数:
def get_file_path(self, index): # 将代理模型索引转换为源模型索引 source_index = self.proxy_model.mapToSource(index) file = self.file_model.filePath(source_index) print(file)
完整修正代码
from PyQt5 import QtCore, 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.lv.clicked.connect(self.get_file_path) self._dirpath = "path/to/folder" # 替换为实际文件夹路径 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) def get_file_path(self, index): # 新增索引转换步骤 source_index = self.proxy_model.mapToSource(index) file = self.file_model.filePath(source_index) print(file) if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) w = Widget() w.show() sys.exit(app.exec_())
额外说明
mapToSource()是QSortFilterProxyModel的核心方法之一,用于在代理模型与源模型的索引间双向转换;对应的反向转换方法是mapFromSource(),你在adjust_root_index中已经用到了。- 该问题在跨平台PyQt开发中均可能出现,并非MacOS特有。
内容的提问来源于stack exchange,提问作者Mazze
相关产品推荐
相关产品推荐

