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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:32:51