You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:20:58