You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取GridContainer子节点尺寸?运行时尺寸值为0的问题

解决GridContainer子节点运行时尺寸获取为0的问题

核心问题原因

GridContainer的布局计算是在节点_ready执行后的帧周期内完成的,再加上你是运行时动态设置NinePatchRect纹理,纹理加载完成的时机也会影响尺寸计算。仅用一次空闲帧等待,可能赶不上布局完成或纹理加载的节点,导致获取到的尺寸还是(0,0)。

具体解决方案

1. 监听节点resized信号(最可靠的方式)

GridContainer及子节点完成布局后都会触发resized信号,这是获取真实尺寸的最佳时机:

# 在外层NinePatchRect所在脚本中
func _ready():
    $OuterNinePatchRect.connect("resized", self, "_on_outer_resized")
    # 动态加载纹理时,先等待纹理加载完成
    var outer_texture = load("res://path/to/outer_nine_patch.tres")
    await outer_texture.loaded
    $OuterNinePatchRect.texture = outer_texture

func _on_outer_resized():
    # 用get_visible_rect()获取实际显示尺寸,比直接取size更准确
    var outer_real_size = $OuterNinePatchRect.get_visible_rect().size
    # 内层NinePatchRect需要减去外层的边框留白
    var inner_target_size = Vector2(
        outer_real_size.x - $OuterNinePatchRect.margin_left - $OuterNinePatchRect.margin_right,
        outer_real_size.y - $OuterNinePatchRect.margin_top - $OuterNinePatchRect.margin_bottom
    )
    $InnerNinePatchRect.rect_size = inner_target_size

2. RichTextLabel的特殊处理

RichTextLabel的尺寸计算依赖文本渲染,除了监听resized,还要配合text_changed信号确保文本加载完成:

func _ready():
    $RichTextLabel.connect("text_changed", self, "_on_label_text_updated")

func _on_label_text_updated():
    # 等待一帧让文本渲染完成
    await get_tree().idle_frame
    var label_real_size = $RichTextLabel.get_visible_rect().size
    # 后续尺寸相关逻辑

3. 锚点与POSITION模式的适配

你设置内层NinePatchRect为layout_mode=POSITION是正确的,锚点会让尺寸受父容器约束,无法手动修改。只要在外层尺寸确定后,直接给内层设置rect_size即可,无需调整锚点。

为什么之前的空闲帧方案失效?

大概率是只等待了一次空闲帧,但此时纹理还未加载完成,或GridContainer的布局还未触发重新计算。需要先确保资源加载完成,再等待布局完成,或直接用resized信号触发,这比固定等待帧更可靠。

内容的提问来源于stack exchange,提问作者DotFX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:35:07