From 2124de7de55a4d0a6fe5397afe2605804e6b3702 Mon Sep 17 00:00:00 2001 From: Rowland <975945824@qq.com> Date: Mon, 26 Jan 2026 16:31:10 +0800 Subject: [PATCH] =?UTF-8?q?ui=E6=9B=BF=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo.py | 100 ++++++++++++++++++++++++++------------ scene/scene_manager.py | 71 +++++++++++++++++++++------ test_project/project.json | 8 +++ 3 files changed, 133 insertions(+), 46 deletions(-) create mode 100644 test_project/project.json diff --git a/demo.py b/demo.py index 6ac9671f..c549e886 100644 --- a/demo.py +++ b/demo.py @@ -5832,37 +5832,77 @@ class MyWorld(CoreWorld): import datetime import os - # 检查是否是有效的项目文件夹 - config_file = os.path.join(project_path, "project.json") - if not os.path.exists(config_file): - print(f"⚠ 选择的不是有效的项目文件夹: {project_path}") + try: + # 检查项目管理器是否已初始化 + if not hasattr(self, 'project_manager') or not self.project_manager: + print("✗ 项目管理器未初始化") + self.add_error_message("项目管理器未初始化") + return False + + # 检查场景管理器是否已初始化 + if not hasattr(self, 'scene_manager') or not self.scene_manager: + print("✗ 场景管理器未初始化") + self.add_error_message("场景管理器未初始化") + return False + + # 检查是否是有效的项目文件夹 + config_file = os.path.join(project_path, "project.json") + if not os.path.exists(config_file): + print(f"⚠ 选择的不是有效的项目文件夹: {project_path}") + self.add_warning_message(f"选择的不是有效的项目文件夹: {project_path}") + return False + + # 读取项目配置 + try: + with open(config_file, "r", encoding="utf-8") as f: + project_config = json.load(f) + except Exception as e: + print(f"✗ 读取项目配置文件失败: {e}") + self.add_error_message(f"读取项目配置文件失败: {e}") + return False + + # 检查场景文件 + scene_file = os.path.join(project_path, "scenes", "scene.bam") + if os.path.exists(scene_file): + # 加载场景 + try: + if self.scene_manager.loadScene(scene_file): + # 更新项目配置 + project_config["scene_file"] = os.path.relpath(scene_file, project_path) + print(f"✓ 场景加载成功: {scene_file}") + else: + print(f"⚠ 场景加载失败: {scene_file}") + self.add_warning_message(f"场景加载失败: {scene_file}") + except Exception as e: + print(f"✗ 加载场景时发生错误: {e}") + self.add_error_message(f"加载场景时发生错误: {e}") + # 继续执行,不阻止项目打开 + + # 更新项目配置 + project_config["last_modified"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + try: + with open(config_file, "w", encoding="utf-8") as f: + json.dump(project_config, f, ensure_ascii=False, indent=4) + except Exception as e: + print(f"✗ 保存项目配置失败: {e}") + self.add_error_message(f"保存项目配置失败: {e}") + + # 更新项目状态 + self.project_manager.current_project_path = project_path + self.project_manager.project_config = project_config + + # 更新窗口标题 + project_name = os.path.basename(project_path) + self._update_window_title(project_name) + + print(f"✓ 项目打开成功: {project_path}") + self.add_success_message(f"项目打开成功: {project_name}") + return True + + except Exception as e: + print(f"✗ 打开项目时发生错误: {e}") + self.add_error_message(f"打开项目时发生错误: {e}") return False - - # 读取项目配置 - with open(config_file, "r", encoding="utf-8") as f: - project_config = json.load(f) - - # 检查场景文件 - scene_file = os.path.join(project_path, "scenes", "scene.bam") - if os.path.exists(scene_file): - # 加载场景 - if self.scene_manager.loadScene(scene_file): - # 更新项目配置 - project_config["scene_file"] = os.path.relpath(scene_file, project_path) - - project_config["last_modified"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - with open(config_file, "w", encoding="utf-8") as f: - json.dump(project_config, f, ensure_ascii=False, indent=4) - - # 更新项目状态 - self.project_manager.current_project_path = project_path - self.project_manager.project_config = project_config - - # 更新窗口标题 - project_name = os.path.basename(project_path) - self._update_window_title(project_name) - - return True def _create_new_project_impl(self, name, path): """创建新项目的具体实现(不依赖Qt)""" diff --git a/scene/scene_manager.py b/scene/scene_manager.py index e3f49121..23be63e0 100644 --- a/scene/scene_manager.py +++ b/scene/scene_manager.py @@ -1450,21 +1450,44 @@ class SceneManager: # 清除当前场景 print("\n清除当前场景...") for model in self.models: - tree_widget.delete_item(model) + if tree_widget: + tree_widget.delete_item(model) + else: + # 直接移除节点 + if not model.isEmpty(): + model.removeNode() # 清除灯光 for light_node in self.Spotlight: - tree_widget.delete_item(light_node) + if tree_widget: + tree_widget.delete_item(light_node) + else: + if not light_node.isEmpty(): + light_node.removeNode() for light_node in self.Pointlight: - tree_widget.delete_item(light_node) + if tree_widget: + tree_widget.delete_item(light_node) + else: + if not light_node.isEmpty(): + light_node.removeNode() - for terrain in self.world.terrain_manager.terrains: - tree_widget.delete_item(terrain) + if hasattr(self.world, 'terrain_manager') and self.world.terrain_manager and hasattr(self.world.terrain_manager, 'terrains'): + for terrain in self.world.terrain_manager.terrains: + if tree_widget: + tree_widget.delete_item(terrain) + else: + if terrain and not terrain.isEmpty(): + terrain.removeNode() # 清除tilesets for tileset_info in self.tilesets: - tree_widget.delete_item(tileset_info['node']) + if tree_widget: + tree_widget.delete_item(tileset_info['node']) + else: + node = tileset_info.get('node') + if node and not node.isEmpty(): + node.removeNode() for light in self.Spotlight: if not light.isEmpty(): @@ -1483,10 +1506,11 @@ class SceneManager: self.tilesets.clear() # 清理Cesium tilesets - for tileset_name, tileset_info in list(self.cesium_integration.tilesets.items()): - if tileset_info['node'] and not tileset_info['node'].isEmpty(): - tileset_info['node'].removeNode() - self.cesium_integration.tilesets.clear() + if hasattr(self, 'cesium_integration') and self.cesium_integration: + for tileset_name, tileset_info in list(self.cesium_integration.tilesets.items()): + if tileset_info and 'node' in tileset_info and tileset_info['node'] and not tileset_info['node'].isEmpty(): + tileset_info['node'].removeNode() + self.cesium_integration.tilesets.clear() for gui in self.world.gui_elements: if not gui.isEmpty(): @@ -1505,7 +1529,8 @@ class SceneManager: print("场景加载失败") return False - tree_widget.create_model_items(scene) + if tree_widget: + tree_widget.create_model_items(scene) # 遍历场景中的所有模型节点 # 用于存储处理后的灯光节点,避免重复处理 processed_lights = [] @@ -2574,28 +2599,42 @@ class SceneManager: def _cleanupAuxiliaryNodes(self): """清理场景中可能存在的辅助节点""" try: + # 检查world和render是否存在 + if not hasattr(self, 'world') or not self.world: + print("world对象不存在,跳过辅助节点清理") + return + + if not hasattr(self.world, 'render') or self.world.render.isEmpty(): + print("render节点不存在,跳过辅助节点清理") + return + # 查找并移除所有坐标轴节点 gizmo_nodes = self.world.render.findAllMatches("**/gizmo*") for node in gizmo_nodes: - if not node.isEmpty(): + if node and not node.isEmpty(): node.removeNode() print(f"清理坐标轴节点: {node.getName()}") # 查找并移除所有选择框节点 selection_box_nodes = self.world.render.findAllMatches("**/selectionBox*") for node in selection_box_nodes: - if not node.isEmpty(): + if node and not node.isEmpty(): node.removeNode() print(f"清理选择框节点: {node.getName()}") # 停止相关的更新任务 - from direct.task.TaskManagerGlobal import taskMgr - taskMgr.remove("updateGizmo") - taskMgr.remove("updateSelectionBox") + try: + from direct.task.TaskManagerGlobal import taskMgr + taskMgr.remove("updateGizmo") + taskMgr.remove("updateSelectionBox") + except Exception as task_e: + print(f"停止任务时出错: {task_e}") print("辅助节点清理完成") except Exception as e: print(f"清理辅助节点时出错: {e}") + import traceback + traceback.print_exc() # ==================== 模型管理 ==================== diff --git a/test_project/project.json b/test_project/project.json new file mode 100644 index 00000000..00041c2e --- /dev/null +++ b/test_project/project.json @@ -0,0 +1,8 @@ +{ + "name": "Test Project", + "path": "/home/hello/EG/test_project", + "created": "2026-01-26 10:00:00", + "last_modified": "2026-01-26 16:22:02", + "version": "1.0", + "scene_file": "scenes/scene.bam" +} \ No newline at end of file