from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QMenu from PyQt5.QtCore import Qt from panda3d.core import GeomNode, ModelRoot class InterfaceManager: """界面管理器 - 处理树形控件和UI交互""" def __init__(self, world): """初始化界面管理器""" self.world = world self.treeWidget = None def setTreeWidget(self, treeWidget): """设置树形控件引用并更新场景树""" self.treeWidget = treeWidget # 添加右键菜单 self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.treeWidget.customContextMenuRequested.connect(self.showTreeContextMenu) # 更新场景树 self.world.scene_manager.updateSceneTree() def onTreeItemClicked(self, item, column): """处理树形控件项目点击事件""" if not item: return # 获取节点对象 nodePath = item.data(0, Qt.UserRole) if nodePath: # 更新选择状态 self.world.selection.updateSelection(nodePath) # 更新属性面板 self.world.property_panel.updatePropertyPanel(item) print(f"树形控件点击: {item.text(0)}") else: # 如果没有节点对象,清除选择 self.world.selection.updateSelection(None) self.world.property_panel.clearPropertyPanel() def showTreeContextMenu(self, position): """显示树形控件的右键菜单""" item = self.treeWidget.itemAt(position) if not item: return # 获取节点对象 nodePath = item.data(0, Qt.UserRole) if not nodePath: return # 创建菜单 menu = QMenu() # 检查是否是GUI元素 if hasattr(nodePath, 'getTag') and nodePath.getTag("gui_type"): # GUI元素菜单 editAction = menu.addAction("编辑") editAction.triggered.connect(lambda: self.world.gui_manager.editGUIElementDialog(nodePath)) deleteAction = menu.addAction("删除GUI元素") deleteAction.triggered.connect(lambda: self.world.gui_manager.deleteGUIElement(nodePath)) duplicateAction = menu.addAction("复制") duplicateAction.triggered.connect(lambda: self.world.gui_manager.duplicateGUIElement(nodePath)) else: # 为模型节点或其子节点添加删除选项 parentItem = item.parent() if parentItem: if self.isModelOrChild(item): deleteAction = menu.addAction("删除") deleteAction.triggered.connect(lambda: self.deleteNode(nodePath, item)) # 显示菜单 menu.exec_(self.treeWidget.viewport().mapToGlobal(position)) def isModelOrChild(self, item): """检查是否是模型节点或其子节点""" while item and item.parent(): if item.parent().text(0) == "模型": return True item = item.parent() return False def deleteNode(self, nodePath, item): """删除节点""" try: # 从场景中移除 nodePath.removeNode() # 如果是模型根节点,从模型列表中移除 if item.parent().text(0) == "模型": if nodePath in self.world.models: self.world.models.remove(nodePath) # 从树形控件中移除 parentItem = item.parent() if parentItem: parentItem.removeChild(item) print(f"成功删除节点: {nodePath.getName()}") # 清空属性面板和选择框 self.world.property_panel.clearPropertyPanel() self.world.selection.updateSelection(None) except Exception as e: print(f"删除节点失败: {str(e)}") def updateSceneTree(self): """更新场景树显示 - 实际实现""" if not self.treeWidget: return print("\n=== 更新场景树 ===") self.treeWidget.clear() # 创建场景根节点 sceneRoot = QTreeWidgetItem(self.treeWidget, ['场景']) # 添加相机节点 cameraItem = QTreeWidgetItem(sceneRoot, ['相机']) cameraItem.setData(0, Qt.UserRole, self.world.cam) print("添加相机节点") # 添加模型节点组 modelsItem = QTreeWidgetItem(sceneRoot, ['模型']) print(f"模型列表中的模型数量: {len(self.world.models)}") # 添加GUI元素节点组 guiItem = QTreeWidgetItem(sceneRoot, ['GUI元素']) print(f"GUI元素数量: {len(self.world.gui_elements)}") # 递归添加节点及其子节点 def addNodeToTree(node, parentItem): print(f"\n处理节点: {node.getName()}") # 创建节点项 nodeItem = QTreeWidgetItem(parentItem, [node.getName()]) nodeItem.setData(0, Qt.UserRole, node) print(f"添加节点: {node.getName()}") # 递归处理所有子节点 for child in node.getChildren(): # 检查是否是有效的模型节点 if (isinstance(child.node(), GeomNode) or child.hasTag("file") or child.getName() == "RootNode" or isinstance(child.node(), ModelRoot)): print(f"处理子节点: {child.getName()}") addNodeToTree(child, nodeItem) else: print(f"跳过节点: {child.getName()}") # 添加所有模型及其子节点 for model in self.world.models: print(f"\n处理根模型: {model.getName()}") addNodeToTree(model, modelsItem) # 添加所有GUI元素 for gui_element in self.world.gui_elements: gui_type = gui_element.getTag("gui_type") if hasattr(gui_element, 'getTag') else "unknown" gui_text = gui_element.getTag("gui_text") if hasattr(gui_element, 'getTag') else "GUI元素" display_name = f"{gui_type}: {gui_text}" guiElementItem = QTreeWidgetItem(guiItem, [display_name]) guiElementItem.setData(0, Qt.UserRole, gui_element) print(f"添加GUI元素: {display_name}") # 添加地板节点 if hasattr(self.world, 'ground'): groundItem = QTreeWidgetItem(sceneRoot, ['地板']) groundItem.setData(0, Qt.UserRole, self.world.ground) print("添加地板节点") # 展开所有节点 self.treeWidget.expandAll() print("=== 场景树更新完成 ===\n") def findTreeItem(self, node, parentItem): """在树形控件中查找指定的节点项""" for i in range(parentItem.childCount()): item = parentItem.child(i) itemNode = item.data(0, Qt.UserRole) if itemNode == node: return item # 递归查找子项 if item.childCount() > 0: found = self.findTreeItem(node, item) if found: return found return None