Maya资产浏览器多列表联动失效问题求助
Maya多层级目录导航脚本二级列表点击无响应问题修复
问题核心原因
脚本中itemClicked函数里的if column == index:判断逻辑错误。所有QTreeWidget仅设置了1列(表头隐藏),点击事件返回的column值永远为0,而二级列表的index为1,0≠1导致后续逻辑完全不执行,这就是点击二级列表无响应的根本原因。
修复步骤
- 删除错误的
if column == index:判断,或替换为if column == 0(所有列表仅1列,点击列必然为0)。 - 增加空值判断,避免因
currentItem()返回None导致的报错。 - 增加索引边界检查,防止点击最后一个列表时触发索引越界错误。
修改后的完整代码
import os import maya.cmds as cmds from PySide2 import QtWidgets, QtGui class AssetBrowser(QtWidgets.QWidget): def __init__(self, asset_dir, parent=None): super(AssetBrowser, self).__init__(parent) self.asset_dir = asset_dir self.levels = 6 # 显示的层级数量 self.list_titles = ["Type", "Category", "Asset", "LOD", "User", "Scene"] # 列表标题 self.file_lists = [] # 存储各层级列表组件的数组 self.initUI() def initUI(self): self.setWindowTitle('Asset Browser') layout = QtWidgets.QVBoxLayout(self) # 添加Logo图片 image_label = QtWidgets.QLabel() pixmap = QtGui.QPixmap(r"D:\WORKSPACE\safeBank\images\safeBank_logoTitle_v001.png") image_label.setPixmap(pixmap) layout.addWidget(image_label) # 项目设置框架 project_frame = QtWidgets.QFrame() project_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) project_layout = QtWidgets.QHBoxLayout(project_frame) layout.addWidget(project_frame) # 设置项目目录按钮 self.set_project_button = QtWidgets.QPushButton("Set Project") self.set_project_button.clicked.connect(self.setProjectDirectory) project_layout.addWidget(self.set_project_button) # 文件夹路径显示框 self.folder_path_lineedit = QtWidgets.QLineEdit() self.folder_path_lineedit.setReadOnly(True) project_layout.addWidget(self.folder_path_lineedit) # 列表布局容器 lists_layout = QtWidgets.QHBoxLayout() layout.addLayout(lists_layout) # 创建各层级列表框架 for i in range(self.levels): frame = QtWidgets.QFrame() frame.setFrameShape(QtWidgets.QFrame.StyledPanel) frame_layout = QtWidgets.QVBoxLayout(frame) lists_layout.addWidget(frame) # 添加列表标题 title_label = QtWidgets.QLabel(self.list_titles[i]) frame_layout.addWidget(title_label) # 创建树形列表组件 file_list_widget = QtWidgets.QTreeWidget() file_list_widget.setHeaderHidden(True) frame_layout.addWidget(file_list_widget) # 绑定点击事件,传递当前列表层级索引 file_list_widget.itemClicked.connect(lambda item, col, index=i: self.itemClicked(item, col, index)) self.file_lists.append(file_list_widget) # 反馈信息栏 feedback_field = QtWidgets.QLabel() layout.addWidget(feedback_field) self.feedback_field = feedback_field # 初始化项目目录 self.setProjectDirectory(self.asset_dir) self.populateFileLists(self.asset_dir) def populateFileLists(self, directory): for level, file_list_widget in enumerate(self.file_lists): file_list_widget.clear() if os.path.exists(directory) and os.listdir(directory): self.populateDirectory(directory, file_list_widget) # 默认进入第一个子目录,填充下一层级 directory = os.path.join(directory, os.listdir(directory)[0]) else: break def populateDirectory(self, directory, file_list_widget): for item_name in sorted(os.listdir(directory)): item_path = os.path.join(directory, item_name) item = QtWidgets.QTreeWidgetItem(file_list_widget) item.setText(0, item_name) if os.path.isdir(item_path): item.setIcon(0, QtGui.QIcon.fromTheme("folder")) def itemClicked(self, item, column, index): print(f"点击列表层级: {index}") print(f"点击列索引: {column}") selected_directory = self.asset_dir valid_path = True # 构建选中路径 for level in range(index + 1): current_item = self.file_lists[level].currentItem() if not current_item: valid_path = False break selected_directory = os.path.join(selected_directory, current_item.text(0)) print(f"当前构建路径: {selected_directory}") # 验证路径并填充下一层级 if valid_path and os.path.isdir(selected_directory): if index + 1 < self.levels: self.populateFileList(selected_directory, self.file_lists[index + 1]) self.feedback_field.setText(selected_directory) else: print(f"无效路径: {selected_directory}") def populateFileList(self, directory, file_list_widget): file_list_widget.clear() self.populateDirectory(directory, file_list_widget) def setProjectDirectory(self, directory=None): if directory is None: directory = QtWidgets.QFileDialog.getExistingDirectory(self, "选择项目目录") if directory: self.asset_dir = directory self.folder_path_lineedit.setText(directory) cmds.workspace(directory, openWorkspace=True) if __name__ == '__main__': import sys app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv) asset_dir = r"D:\WORKSPACE\new_folderStructure\GF\3D\ASSETS" asset_browser = AssetBrowser(asset_dir) asset_browser.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者Thomas Burton
相关产品推荐
相关产品推荐

