如何调整QTreeView代码实现含OBJ文件的文件夹嵌套展示
解决QTreeView只显示包含OBJ文件的嵌套文件夹问题
我懂你想要的效果——只展示那些包含(或嵌套包含)OBJ文件的文件夹,同时在QTreeView里清晰体现它们的层级结构。下面是完整的代码实现,我会拆解关键逻辑帮你理解:
首先我们需要自定义一个QFileSystemModel子类,核心是重写filterAcceptsRow方法,让它递归检查文件夹下是否存在OBJ文件(包括子文件夹里的),这样就能精准筛选出符合要求的文件夹。
import os import sys from Qt import QtGui, QtWidgets, QtCore class OBJFolderModel(QtWidgets.QFileSystemModel): def __init__(self, parent=None): super().__init__(parent) # 设置模型只识别文件夹,排除当前目录和上级目录的占位符 self.setFilter(QtCore.QDir.AllDirs | QtCore.QDir.NoDotAndDotDot) def has_obj_files(self, dir_path): """递归检查目录下(含子目录)是否存在.obj文件""" for root, _, files in os.walk(dir_path): for file in files: # 不区分大小写匹配OBJ文件 if file.lower().endswith('.obj'): return True return False def filterAcceptsRow(self, source_row, source_parent): # 获取当前项的索引对象 index = self.index(source_row, 0, source_parent) # 获取当前项对应的本地路径 file_path = self.filePath(index) # 只处理文件夹,检查是否符合OBJ文件存在的条件 if self.isDir(index): return self.has_obj_files(file_path) # 我们只关心文件夹,文件直接过滤掉 return False class MainWindow(QtWidgets.QMainWindow): def __init__(self, target_dir=None, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.resize(350, 600) self.setWindowTitle("OBJ文件夹浏览器") # 创建TreeView组件并设为主窗口中心部件 self.tree_view = QtWidgets.QTreeView() self.setCentralWidget(self.tree_view) # 初始化自定义模型 self.model = OBJFolderModel() if target_dir and os.path.exists(target_dir): # 设置模型的根目录,同时获取根目录对应的索引 root_index = self.model.setRootPath(target_dir) self.tree_view.setRootIndex(root_index) # 配置TreeView的显示规则 self.tree_view.setModel(self.model) # 隐藏默认的大小、类型、修改时间列,只保留文件夹名称列 self.tree_view.hideColumn(1) self.tree_view.hideColumn(2) self.tree_view.hideColumn(3) # 启用展开/折叠的动画效果 self.tree_view.setAnimated(True) # 让名称列自动适配内容宽度 self.tree_view.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) # 替换成你要扫描的目标目录 target_directory = "/path/to/your/target/folder" window = MainWindow(target_directory) window.show() sys.exit(app.exec_())
关键细节说明:
自定义模型的过滤逻辑:
has_obj_files函数负责递归遍历目录,只要找到任意一个OBJ文件就返回True,确保父文件夹即使本身没有OBJ,但子文件夹有也能被显示。filterAcceptsRow方法是模型的核心过滤入口,只允许符合条件的文件夹通过筛选。
TreeView的界面优化:
- 隐藏冗余列让界面更简洁,只保留核心的文件夹名称。
- 动画效果和自动列宽能提升交互体验,让层级结构更清晰。
可选优化建议:
如果你的目标目录层级很深、文件很多,递归遍历可能会有性能问题,可以给has_obj_files加个缓存机制,避免重复检查同一个文件夹;要是需要实时监控文件夹变化(比如新增/删除OBJ后自动更新视图),可以在模型里加入QFileSystemWatcher来监听目录变动,触发重新过滤。
内容的提问来源于stack exchange,提问作者JokerMartini
相关产品推荐
相关产品推荐

