1
0
forked from Rowland/EG
EG/ui/interface_manager.py

205 lines
7.7 KiB
Python

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:
# 从场景中移除
self.world.property_panel.removeActorForModel(nodePath)
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)}")
lightItem = QTreeWidgetItem(sceneRoot,['灯光'])
# 递归添加节点及其子节点
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}")
for light_element in self.world.Spotlight:
addNodeToTree(light_element,lightItem)
for light_element in self.world.Pointlight:
addNodeToTree(light_element,lightItem)
# 添加地板节点
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