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

如何在QListView中隐藏文件夹仅显示文件?解决视图重置问题

解决QListView设置文件过滤后重置到根目录的问题

问题原因

当你为mainListViewModel设置QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files过滤规则后,该模型只会加载文件节点,不会加载文件夹节点。在update_main_list_view方法中,你传入的new_path是文件夹路径,调用self.mainListViewModel.index(new_path)时,模型无法找到该文件夹对应的索引,QListView就会默认切换到根目录(空路径)。

解决方案

不要直接修改QFileSystemModel的过滤规则,而是给QListView搭配QSortFilterProxyModel,通过代理模型过滤掉文件夹,只显示文件。这样源模型仍能正常识别文件夹路径,保证setRootIndex生效,同时视图只展示文件。

修改后的完整代码

from PySide2 import QtCore, QtWidgets

class FileOnlyProxyModel(QtCore.QSortFilterProxyModel):
    def filterAcceptsRow(self, source_row, source_parent):
        source_model = self.sourceModel()
        index = source_model.index(source_row, 0, source_parent)
        # 只接受文件,过滤掉文件夹
        return source_model.isFile(index)

class AssetBrowser(QtWidgets.QWidget):
    def __init__(self):
        super(AssetBrowser, self).__init__()
        
        self.setWindowTitle("Tree and List View Example")
        self.setGeometry(100, 100, 400, 500)
        self.treeView = QtWidgets.QTreeView(self)
        self.mainListView = QtWidgets.QListView(self)
        self.search_line_edit = QtWidgets.QLineEdit(self)       
        
        # Create the layout
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.treeView)
        layout.addWidget(self.mainListView)
        layout.addWidget(self.search_line_edit)
        
        # Create a central widget and set the layout
        central_widget = QtWidgets.QWidget(self)
        central_widget.setLayout(layout)

        ### treeViewViewStart        
        self.treeViewModel = QtWidgets.QFileSystemModel() 
        self.treeViewModel.setRootPath('')
        self.treeViewModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.AllDirs)
        self.treeViewProxyModel = QtCore.QSortFilterProxyModel()
        self.treeViewProxyModel.setSourceModel(self.treeViewModel)
        self.treeView.setModel(self.treeViewProxyModel)
        self.treeView.setRootIndex(self.treeViewProxyModel.mapFromSource(self.treeViewModel.index("D:/")))       
        self.treeView.setColumnHidden(1, True)
        self.treeView.setColumnHidden(2, True)
        self.treeView.setColumnHidden(3, True)
        self.treeView.setHeaderHidden(True)
        self.treeView.clicked.connect(self.update_main_list_view)
        ### treeViewViewEnd
        
        ### listViewStart
        self.mainListViewModel = QtWidgets.QFileSystemModel()        
        self.mainListViewModel.setRootPath('') 
        # 源模型保留能识别文件夹和文件的过滤规则
        self.mainListViewModel.setFilter(QtCore.QDir.NoDotAndDotDot | QtCore.QDir.AllDirs | QtCore.QDir.Files)
        
        # 添加文件过滤代理
        self.listViewProxyModel = FileOnlyProxyModel()
        self.listViewProxyModel.setSourceModel(self.mainListViewModel)
        
        self.mainListView.setIconSize(QtCore.QSize(100, 100))
        self.mainListView.setViewMode(QtWidgets.QListView.IconMode)
        self.mainListView.setResizeMode(QtWidgets.QListView.Adjust)
        self.mainListView.setMovement(QtWidgets.QListView.Static)
        ### listViewEnd       
        
        # 给ListView设置代理模型
        self.mainListView.setModel(self.listViewProxyModel)
        # 转换索引到代理模型
        source_index = self.mainListViewModel.index("D:/")
        proxy_index = self.listViewProxyModel.mapFromSource(source_index)
        self.mainListView.setRootIndex(proxy_index)

    def update_main_list_view(self, index):
        selected_index = self.treeViewProxyModel.mapToSource(index)
        new_path = self.treeViewModel.filePath(selected_index)
        
        print(new_path)
        # 获取源模型的索引,转换为代理模型的索引后设置
        source_index = self.mainListViewModel.index(new_path)
        proxy_index = self.listViewProxyModel.mapFromSource(source_index)
        self.mainListView.setRootIndex(proxy_index)
   
if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    window = AssetBrowser()
    window.show()
    app.exec_()

关键修改点

  1. 自定义FileOnlyProxyModel,重写filterAcceptsRow方法,只接受文件节点。
  2. mainListViewModel的过滤规则改为包含文件夹和文件,保证能识别文件夹路径。
  3. QListView使用代理模型,设置根索引时需要将源模型的索引转换为代理模型的索引。
  4. 在update_main_list_view方法中,同样需要将源模型的路径索引转换为代理模型的索引后再设置给ListView。

内容的提问来源于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 17:13:08