Godot EditorScript弹出EditorFileDialog失败报is_inside_tree错误
EditorScript中弹出EditorFileDialog失败问题
问题复现
在开发自定义JSON导入生成Tilemap功能时,编写如下EditorScript测试代码尝试弹出本地文件选择框:
tool extends EditorScript func _run(): var fileDialog = EditorFileDialog.new() fileDialog.mode = EditorFileDialog.MODE_OPEN_FILE fileDialog.access = EditorFileDialog.ACCESS_FILESYSTEM fileDialog.popup() ...
运行后无窗口弹出,调试器输出以下报错:
scene/gui/control.cpp:2154 - Condition "!is_inside_tree()" is true. scene/2d/canvas_item.cpp:469 - Condition "!is_inside_tree()" is true. Returned: get_transform() scene/2d/canvas_item.cpp:939 - Condition "!is_inside_tree()" is true. Returned: Rect2() scene/gui/control.cpp:2128 - Condition "!is_inside_tree()" is true. scene/gui/control.cpp:2128 - Condition "!is_inside_tree()" is true. ./scene/main/node.h:269 - Condition "!data.tree" is true. Returned: nullptr
报错原因
所有Godot的GUI控件必须被加入场景树后才能正常执行弹出、渲染、交互逻辑。直接通过new()创建的EditorFileDialog不属于任何现有节点的子节点,未进入场景树,调用popup()时引擎底层校验is_inside_tree()不通过,因此无法正常显示。
解决方案
方案1:手动创建对话框节点并挂载到编辑器根节点
这是自由度最高的方案,可自定义对话框的所有属性、过滤规则、按钮逻辑:
tool extends EditorScript func _run(): var fileDialog = EditorFileDialog.new() # 基础配置 fileDialog.mode = EditorFileDialog.MODE_OPEN_FILE fileDialog.access = EditorFileDialog.ACCESS_FILESYSTEM # 可选:添加JSON文件过滤 fileDialog.add_filter("*.json ; JSON配置文件") # 将对话框加入编辑器场景树,这一步是核心 EditorInterface.get_base_control().add_child(fileDialog) # 绑定文件选中回调 fileDialog.file_selected.connect(func(file_path): # 此处编写读取JSON、生成Tilemap的业务逻辑 print("选中文件路径:", file_path) # 逻辑执行完销毁临时对话框 fileDialog.queue_free() ) # 绑定窗口关闭回调,点击取消时也销毁节点避免残留 fileDialog.popup_hide.connect(func(): if is_instance_valid(fileDialog): fileDialog.queue_free() ) # 居中弹出窗口,参数为窗口占屏幕比例 fileDialog.popup_centered_ratio(0.75)
方案2:直接复用编辑器内置的全局文件对话框
如果不需要自定义复杂逻辑,可直接调用编辑器已有的文件对话框实例,省去手动创建、销毁节点的步骤:
tool extends EditorScript func _run(): var dialog = EditorInterface.file_dialog # 先断开之前绑定的同信号,避免多次运行脚本导致重复触发 if dialog.file_selected.is_connected(_on_file_selected): dialog.file_selected.disconnect(_on_file_selected) # 配置对话框参数 dialog.mode = EditorFileDialog.MODE_OPEN_FILE dialog.access = EditorFileDialog.ACCESS_FILESYSTEM dialog.clear_filters() dialog.add_filter("*.json ; JSON配置文件") # 绑定选中回调 dialog.file_selected.connect(_on_file_selected) # 弹出窗口 dialog.popup_centered_ratio(0.75) func _on_file_selected(file_path): # 此处编写读取JSON、生成Tilemap的业务逻辑 print("选中文件路径:", file_path) # 用完断开信号避免后续其他功能触发该回调 EditorInterface.file_dialog.file_selected.disconnect(_on_file_selected)
注意事项
- 所有
tool模式下在编辑器运行时创建的GUI控件,都必须挂载到编辑器场景树内的现有节点(通常取EditorInterface.get_base_control()作为根挂载点)才能正常显示 - 临时创建的节点、绑定的信号要及时清理,避免多次运行脚本导致内存泄漏、信号重复触发等问题
内容的提问来源于stack exchange,提问作者macrico
相关产品推荐
相关产品推荐

